当前位置: 首页 > article >正文

RestTemplate 发送 JSON 请求时为何要手动序列化对象?

在使用 RestTemplate 发送 HTTP 请求时,我们经常会遇到这样的问题:直接传递 Java 对象作为请求体可能会导致请求失败,而改为 手动序列化为 JSON 字符串 后,接口才能正常接收。这篇文章将深入解析 为什么 RestTemplate 需要手动序列化 JSON,以及推荐的最佳实践。

1. 直接传递 Java 对象可能导致的问题

通常,我们可能会这样写代码:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HkRequest request = new HkRequest();
request.setEndDate("2024-03-12");

HttpEntity<HkRequest> entity = new HttpEntity<>(request, headers);

ResponseEntity<BaseResponse<HkData>> response = restTemplate.exchange(
    marketingReturnUrl + "/channel/hk",
    HttpMethod.POST,
    entity,
    new ParameterizedTypeReference<BaseResponse<HkData>>() {}
);

乍一看,这段代码是符合 RestTemplate 规范的,但在某些情况下,它可能会 无法正确序列化 request 对象,从而导致请求失败。主要原因有:

  • RestTemplate 可能解析为 application/x-www-form-urlencoded 而非 application/json
  • HttpMessageConverter 可能无法正确转换对象,特别是当 HkRequest 不是标准的可序列化 POJO 时
  • 如果 HkRequest 内部包含复杂类型(如 DateList<T> 等),Spring 可能无法正确处理

2. 解决方案:手动序列化为 JSON 字符串

为了确保 RestTemplate 发送的请求体是符合 application/json 规范的,我们可以手动将 Java 对象转换为 JSON 字符串:

推荐方式 1:使用 FastJSON 进行手动序列化

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HkRequest request = new HkRequest();
request.setEndDate("2024-03-12");

// 手动序列化对象为 JSON 字符串
HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(request), headers);

ResponseEntity<BaseResponse<HkData>> response = restTemplate.exchange(
    marketingReturnUrl + "/channel/hk",
    HttpMethod.POST,
    entity,
    new ParameterizedTypeReference<BaseResponse<HkData>>() {}
);

推荐方式 2:使用 Jackson 进行手动序列化

ObjectMapper objectMapper = new ObjectMapper();
String jsonRequest = objectMapper.writeValueAsString(request);

HttpEntity<String> entity = new HttpEntity<>(jsonRequest, headers);

推荐方式 3:确保 RestTemplate 自动处理 JSON

在某些情况下,如果 RestTemplate 能正确识别 HttpMessageConverter,可以直接使用 Java 对象:

HttpEntity<HkRequest> entity = new HttpEntity<>(request, headers);

⚠️ 但这需要确保 Jackson 依赖存在,并且 HkRequest 是标准的 POJO,否则可能导致解析失败!

3. RestTemplate 默认的 HttpMessageConverter

Spring RestTemplate 默认使用 MappingJackson2HttpMessageConverter(如果 Jackson 依赖存在),但在某些情况下:

  • RestTemplate 可能 未能正确加载 JSON 转换器
  • Spring 可能会 将对象转换为 application/x-www-form-urlencoded,而不是 application/json

手动转换为 JSON 字符串可以 避免这些潜在的问题

4. 总结:最佳实践

方式适用情况是否推荐
JSON.toJSONString(request)FastJSON 环境,手动序列化✅ 推荐
ObjectMapper.writeValueAsString(request)Jackson 生态,手动序列化✅ 推荐
HttpEntity<>(request, headers)仅当 RestTemplate 默认支持 JSON 序列化⚠️ 可能有问题

最佳实践:手动转换 JSON 字符串,避免 RestTemplate 误解析,确保 Content-Typeapplication/json


http://www.kler.cn/a/584195.html

相关文章:

  • 用SpringBoot做一个web小案例实现登录
  • 16天 - 单例模式有哪几种实现?如何保证线程安全?什么是策略模式?一般用在什么场景?什么是模板方法模式?一般用在什么场景?
  • Linux中的基本指令(下)
  • 【文献阅读】Zotero 新手完全教程:安装、使用与插件
  • Python Cookbook-4.2 通过列表推导构建列表
  • 【C++】 —— 笔试刷题day_3
  • C++ Primer Plus第十二章课后习题总结
  • 人工智能与我何干
  • 新闻网页信息抽取
  • OKHttp3 源码阅读 - Kotlin版本
  • IIC通信协议详解与STM32实战指南
  • 如何在Ubuntu上构建编译LLVM和ISPC,以及Ubuntu上ISPC的使用方法
  • Fiora聊天系统本地化部署:Docker搭建与远程在线聊天的实践指南
  • 广告牌倾斜安全监测:保障公共安全的智能化解决方案
  • OpenMCU(三):STM32F103 FreeRTOS移植
  • 【学习笔记】《逆向工程核心原理》03.abex‘crackme-2、函数的调用约定、视频讲座-Tut.ReverseMe1
  • 【LangChain】理论及应用实战(4):Memory
  • 视觉语言模型VLM发展脉络
  • windows第十二章 MFC控件常用消息
  • FANUC机器人几种常用的通讯网络及接口