使用WebClient的BodyInserters同时传递两个请求对象调用接口问题咨询
问题根因
Spring WebFlux(含Spring MVC)中@RequestBody注解仅允许在单个接口上声明1次,因为HTTP请求的请求体数据流仅支持读取一次,你当前提供的目标服务端接口本身写法不符合Spring规范,无法正常接收两个独立的JSON对象。
你之前使用MultipartBodyBuilder、MultiValueMap不生效的原因有两个:
- 你最终发起请求时body里传的还是单个
reqDto1,没用到你构造的多参数结构 @RequestBody默认接收JSON格式请求体,和MultipartBodyBuilder生成的form-data格式不匹配
解决方案
方案1:封装统一请求DTO(最推荐,JSON接口标准写法)
第一步:修改服务端代码
新增统一的请求DTO类,把两个参数封装为同一个对象的属性:
import lombok.Data; import javax.validation.Valid; @Data public class TransCombineReqDto { @Valid private TransReqDto1 reqDto1; @Valid private TransReqDto2 reqDto2; }
修改接口代码,仅保留一个@RequestBody:
@PostMapping("") @ApiOperation(value = "test", notes = "test") public Mono<?> transPost(@Valid @RequestBody TransCombineReqDto reqDto) { return testService.function(reqDto.getReqDto1(), reqDto.getReqDto2()); }
第二步:修改客户端代码
构造封装后的DTO直接发送即可:
public Mono<RespDto> function(TransReqDto1 reqDto1, TransReqDto2 reqDto2, String token) { TransCombineReqDto combineReq = new TransCombineReqDto(); combineReq.setReqDto1(reqDto1); combineReq.setReqDto2(reqDto2); return client.post() .uri("/api") .body(BodyInserters.fromValue(combineReq)) .headers(h -> h.setBearerAuth(token.split(" ")[1])) .retrieve() .bodyToMono(RespDto.class); }
方案2:改用form-data格式提交(适合文件上传等混合场景)
如果不想新增DTO,可以调整服务端注解适配多部分表单提交:
第一步:修改服务端注解
把@RequestBody替换为@RequestPart:
@PostMapping("") @ApiOperation(value = "test", notes = "test") public Mono<?> transPost(@Valid @RequestPart TransReqDto1 reqDto1, @Valid @RequestPart TransReqDto2 reqDto2) { return testService.function(reqDto1, reqDto2); }
第二步:修改客户端代码
用你之前构造的Multipart参数发送请求:
public Mono<RespDto> function(TransReqDto1 reqDto1, TransReqDto2 reqDto2, String token) { MultipartBodyBuilder builder = new MultipartBodyBuilder(); builder.part("reqDto1", reqDto1); builder.part("reqDto2", reqDto2); MultiValueMap<String, HttpEntity<?>> parts = builder.build(); return client.post() .uri("/api") .body(BodyInserters.fromMultipartData(parts)) .headers(h -> h.setBearerAuth(token.split(" ")[1])) .retrieve() .bodyToMono(RespDto.class); }
内容的提问来源于stack exchange,提问作者Sang Kim
相关产品推荐
相关产品推荐

