Spring Boot中WebClient如何发送含多值JSON结构的请求体
Spring Boot 发送指定嵌套结构JSON请求的标准实现
目标待发送请求体JSON结构如下:
{ "a": "valueA1", "b": { "b1": "valueB1", "b2": "valueB2" } }
Spring生态下有两种主流标准实现,分别对应官方推荐的响应式客户端WebClient,和传统阻塞式客户端RestTemplate,核心逻辑都是通过JSON序列化自动处理嵌套结构,不需要手动拼接请求报文。
方式1:WebClient 实现(Spring 5+ 官方推荐,兼容阻塞/响应式场景)
步骤1:定义映射结构(解决多DTO处理问题的核心)
按照JSON的层级关系定义关联的DTO类即可,不需要额外做DTO的特殊转换:
// 外层请求体映射类 public class PostRequest { private String a; private InnerB b; // 无参构造是JSON序列化必须的,也可以用Lombok@Data注解自动生成getter/setter/构造 public PostRequest() {} public PostRequest(String a, InnerB b) { this.a = a; this.b = b; } public String getA() {return a;} public void setA(String a) {this.a = a;} public InnerB getB() {return b;} public void setB(InnerB b) {this.b = b;} } // b字段对应的内层嵌套对象映射类 public class InnerB { private String b1; private String b2; public InnerB() {} public InnerB(String b1, String b2) { this.b1 = b1; this.b2 = b2; } public String getB1() {return b1;} public void setB1(String b1) {this.b1 = b1;} public String getB2() {return b2;} public void setB2(String b2) {this.b2 = b2;} }
如果是临时简单调用场景,不想单独定义DTO,也可以直接用Map嵌套构造请求体,序列化后结构完全一致。
步骤2:编写请求发送逻辑
// 建议将WebClient配置为全局Bean统一管理,不需要每次调用新建实例 WebClient webClient = WebClient.builder() .baseUrl("目标服务的根路径") .build(); // 构造请求参数 InnerB innerB = new InnerB("valueB1", "valueB2"); PostRequest requestBody = new PostRequest("valueA1", innerB); // 发送POST请求,以下是阻塞式获取响应的写法,适配非响应式项目 String responseStr = webClient.post() .uri("/目标接口的相对路径") .contentType(MediaType.APPLICATION_JSON) .bodyValue(requestBody) // 直接传入嵌套对象,框架自动序列化为目标JSON结构 .retrieve() .bodyToMono(String.class) // 若需要结构化响应,将String替换为自定义的响应DTO类即可 .block(); // 响应式项目场景下不需要调用block(),直接返回Mono/Flux类型的响应结果给下游即可
之前遇到的多DTO处理异常,本质是没有建立DTO之间的嵌套关联关系,不需要手动拼接多值映射、JSON字符串,直接传入嵌套结构的Java对象,Jackson序列化组件会自动生成符合要求的报文结构。
方式2:RestTemplate 实现(传统阻塞式Spring项目常用)
老项目如果使用RestTemplate作为HTTP客户端,实现逻辑一致:
// 建议将RestTemplate配置为全局Bean统一管理 RestTemplate restTemplate = new RestTemplate(); // 构造请求体,和WebClient逻辑完全一致,既可以用上面定义的嵌套DTO,也可以用嵌套Map InnerB innerB = new InnerB("valueB1", "valueB2"); PostRequest requestBody = new PostRequest("valueA1", innerB); // 构造请求实体 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<PostRequest> requestEntity = new HttpEntity<>(requestBody, headers); // 发送POST请求 ResponseEntity<String> response = restTemplate.postForEntity( "目标接口完整地址", requestEntity, String.class // 替换为自定义响应DTO即可接收结构化响应 );
内容的提问来源于stack exchange,提问作者Saksham Behl
相关产品推荐
相关产品推荐

