一 问题描述
微服务重构
从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@RequestParambinds 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参数不能为空");
    });
}
