一 问题描述
微服务重构
从webmvc重构为webflux,其他业务逻辑基本没更改
出现报错如下:1
2
3
4
5
6
7
8
9org.springframework.web.server.ServerWebInputException: 400 BAD_REQUEST "Required String parameter 'drawPath' is not present"
at org.springframework.web.reactive.result.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:114) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.reactive.result.method.annotation.AbstractNamedValueArgumentResolver.lambda$getDefaultValue$1(AbstractNamedValueArgumentResolver.java:215) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at reactor.core.publisher.MonoSupplier.subscribe(MonoSupplier.java:56) [reactor-core-3.3.0.RELEASE.jar:3.3.0.RELEASE]
at reactor.core.publisher.Mono.subscribe(Mono.java:4087) ~[reactor-core-3.3.0.RELEASE.jar:3.3.0.RELEASE]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75) ~[reactor-core-3.3.0.RELEASE.jar:3.3.0.RELEASE]
at reactor.core.publisher.Operators.complete(Operators.java:132) ~[reactor-core-3.3.0.RELEASE.jar:3.3.0.RELEASE]
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:144) [reactor-core-3.3.0.RELEASE.jar:3.3.0.RELEASE]
...
Post请求 参数通过formdata方式传入则报以上错误
但是通过url参数则能正常请求
java代码如下:1
2
3
4 "/appnewuser") (
public Mono<GiftPacksDrawRecordDTO> drawNewUserPacks(@RequestParam String drawPath) {
....
}
二 查看webflux文档
The Servlet API “request parameter” concept conflates query parameters, form data, and multiparts into one. However, in WebFlux, each is accessed individually through
ServerWebExchange
. While@RequestParam
binds to query parameters only, you can use data binding to apply query parameters, form data, and multiparts to a command object.
文档中已经明确说明了webflux中,该注解仅支持url传参方式
三 解决方案
由于重构不能影响到前端原有调用,所以不太可能先把所有调用了接口的地方全部调整一遍,所以只能服务端做兼容,方案如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34/**
* 领取APP端新人礼包
*
* @return
* @throws BaseException
*/
"/appnewuser") (
public Mono<GiftPacksDrawRecordDTO> drawNewUserPacks(ServerWebExchange serverWebExchange) throws BaseException {
String drawPath = serverWebExchange.getRequest().getQueryParams().getFirst("drawPath");
String accountId = JkSecurityUtil.getAccountId();
if (StringUtils.isNotBlank(drawPath)) {
return Mono.justOrEmpty(this.drawPack(drawPath, accountId));
}
Mono<String> drawPathMono1 = serverWebExchange.getMultipartData()
.flatMap(multiValueMap -> Mono.justOrEmpty(multiValueMap.getFirst("drawPath")))
.flatMap(drawPathPart -> drawPathPart.content().elementAt(0))
.map(content -> content.toString(Charset.defaultCharset()))
.defaultIfEmpty("");
Mono<String> drawPathMono2 = serverWebExchange.getFormData()
.flatMap(formDataMap -> Mono.justOrEmpty(formDataMap.getFirst("drawPath")))
.defaultIfEmpty("");
return Mono.zip(drawPathMono1, drawPathMono2).map(tuple -> {
String t1 = tuple.getT1();
String t2 = tuple.getT2();
if (StringUtils.isNotBlank(t1)) {
return this.drawPack(t1, accountId);
} else if (StringUtils.isNotBlank(t2)) {
return this.drawPack(t2, accountId);
}
throw new BusinessException("drawPath参数不能为空");
});
}