遇到的问题:

1、使用注解式:在js中使用ajax提交post数据name,在controller中使用@RequestBody无法获取到数据。

2、使用函数式:在js中使用ajax提交post数据name,在hander中怎么使用ServerRequest获取到提交的数据name的值呢?

相关尝试:

在注解式中:开始我使用的是@RequestBody String name,但是获取到的值是空的。然后看到网上的有用@RequestBody final Mono name,但是这种也没有获取到值。

在函数式中:我想直接从request中拿,使用方法resolveBodyFromRequest将serverHttpRequest.getBody得到的mono数据转为String.但是仍然拿到的值是空的。

麻烦用过webflux获取到post请求参数的大佬帮忙看看应该怎么获取?

相关代码

// 注解式的请求js

$.ajax({

type: 'POST',

url: "/postController/find",

data: {

name: "aa",

},

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

// 注解式 controller

@RestController

@RequestMapping("/postController")

public class PostController {

@PostMapping(value = "/find", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)

public Mono find(@RequestBody final String name) {

// 这里一直拿不到 post过来的name ???

System.out.println(name);

return Mono.justOrEmpt(name);

}

}

// 函数式的请求js

$.ajax({

type: 'POST',

url: "/post/find",

data: {

name: "aa",

},

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

// 函数式 router

@Configuration

public class PostRouter {

@Bean

public RouterFunction route(PostHandler handler) {

return RouterFunctions

.route(RequestPredicates.POST("/post/find")

.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),

handler::find);

}

}

// 函数式 handle

@Component

public class PostHandler {

public Mono find(ServerRequest serverRequest){

// 这里一直拿不到 post过来的data ???

String str =readRequestData((ServerHttpRequest)serverRequest);

return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)

.body(BodyInserters.fromObject(str));

}

public String readRequestData(ServerHttpRequest serverHttpRequest) {

String bodyData = "";

String method = serverHttpRequest.getMethodValue();

if ("POST".equals(method)) {

bodyData = resolveBodyFromRequest(serverHttpRequest);

} else if ("GET".equals(method)) {

bodyData = getContentByGetRequest(serverHttpRequest);

}

return bodyData;

}

private String getContentByGetRequest(ServerHttpRequest serverHttpRequest) {

Map requestQueryParams = serverHttpRequest.getQueryParams().toSingleValueMap();

StringBuffer s = new StringBuffer();

String content = "";

requestQueryParams.forEach((k, v) -> {

System.out.println(k + "  v:" + v);

s.append(k + "=" + v + "&");

});

if (null != s && !s.equals("")) {

content = s.toString().substring(0, s.toString().lastIndexOf('&'));

}

return content;

}

/**

* * 从Flux中获取字符串的方法

* @return 请求体

*/

private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {

//获取请求体

Flux body = serverHttpRequest.getBody();

System.out.println(body);

AtomicReference bodyRef = new AtomicReference<>();

body.subscribe(buffer -> {

CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());

DataBufferUtils.release(buffer);

bodyRef.set(charBuffer.toString());

});

//获取request body

return bodyRef.get();

}

}

你期待的结果是什么?实际看到的错误信息又是什么?

回答

1、函数式:

//1、若是form-data形式提交表单内容,即Content-Type: application/x-www-form-urlencoded;可以通过ServerWebExchange 获取

$.ajax({

type: 'POST',

url: "/post/findform",

data: {

name: "aa",

sex:"n"

},

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

// route:

@Configuration

public class PostRouter {

@Bean

public RouterFunction postroute(PostHandler handler) {

return RouterFunctions.route(RequestPredicates.POST("/post/findform")

.and(RequestPredicates.accept(MediaType.APPLICATION_FORM_URLENCODED)),handler::findform);

}

}

// handle:

public Mono findform(ServerRequest request){

// 获取form data,在方法中添加ServerWebExchange对象,使用方法getFormData

ServerWebExchange exchange = request.exchange();

Mono> formData =exchange.getFormData();

return formData.flatMap(map -> {

System.out.println(map.get("name").get(0));

System.out.println(map.get("sex").get(0));

return ServerResponse.ok().contentType(MediaType.APPLICATION_STREAM_JSON)

.body(BodyInserters.fromObject(map));

});

}

// 2、若是application/json的形式提交表单

$.ajax({

type: 'POST',

url: "/post/findjson",

data: JSON.stringify({

"name": "aa"

}),

contentType:"application/json",

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

// route:

@Configuration

public class PostRouter {

@Bean

public RouterFunction postroute(PostHandler handler) {

return RouterFunctions.route(RequestPredicates.POST("/post/findjson")

.and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),handler::find)

}

}

// handle:直接通过map映射获取

public Mono find(ServerRequest serverRequest){

Mono body = serverRequest.bodyToMono(Map.class);

return body.flatMap(map -> {

String name = (String) map.get("name");

System.out.println(name);

return ServerResponse.ok().contentType(MediaType.APPLICATION_STREAM_JSON)

.body(BodyInserters.fromObject(name));

});

}

2、注解式

若是get请求,可通过@RequestParam或直接获取

// get形式提交,下面两种形式都可以直接获取到请求参数

@GetMapping("/save")

private Mono save(final User user){

System.out.println(user.getName());

return Mono.justOrEmpty(userService.save(user));

}

@GetMapping("/save1")

private Mono save(@RequestParam final String name,@RequestParam final String sex){

System.out.println(name);

return Mono.justOrEmpty(userService.save(new User(name,sex)));

}

若是Post请求,当请格式分别为json或表单格式,json使用@RequestBody获取,form格式通过实体映射或使用ServerWebExchange获取

$.ajax({

type: 'POST',

url: "/postController/json",

data: JSON.stringify({

"name": "aa",

"sex":"m"

}),

contentType:"application/json",

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

$.ajax({

type: 'POST',

url: "/postController/jsonS",

data: JSON.stringify({

"name": "aa",

"sex":"m"

}),

contentType:"application/json",

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

$.ajax({

type: 'POST',

url: "/postController/form",

data: {

name: "bb",

sex:"m"

},

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

$.ajax({

type: 'POST',

url: "/postController/formS",

data: {

name: "bb",

sex:"m"

},

dataType: "json",

success: function (data) {

console.log(data);

},error:function () {

console.log("error");

}

});

// controller

@RestController

@RequestMapping("/postController")

public class PostController {

/**

* 通过@RequestBody获取提交的application/json数据

* @param

* @return

*/

@PostMapping(value = "/json",produces = MediaType.APPLICATION_STREAM_JSON_VALUE)

public Mono json(@RequestBody String user) {

System.out.println("json:"+user);

return Mono.just(user);

}

/**

* 通过实体映射获取post的请求体 application/json数据

* @param user

* @return

*/

@PostMapping(value = "/jsonS",produces = MediaType.APPLICATION_STREAM_JSON_VALUE)

public Mono jsonS(@RequestBody User user) {

System.out.println("jsonS:"+ user);

return Mono.just(user.toString());

}

/**

* 通过实体映射获取表单数据

* request:Content-Type: application/x-www-form-urlencoded

* @param user

* @return

*/

@PostMapping(value = "/form", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)

public Mono save(User user) {

System.out.println("form:"+user);

return Mono.justOrEmpty(user);

}

/**

* 通过ServerWebExchange获取表单数据

* request:Content-Type: application/x-www-form-urlencoded

* @param exchange

* @return

*/

@PostMapping(value = "/formS", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)

public Mono save(ServerWebExchange exchange) {

Mono> formData =exchange.getFormData();

return formData.flatMap(map -> {

System.out.println("formS:"+map);

return Mono.justOrEmpty(map.toString());

});

}

}

采用注解式怎么解决呢?

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐