前言:

重要,RestTemplate在SpringBoot项目里即便通过HttpMessageConverters添加了Fastjson且优先级比jackson要高也不会在RestTemplate里生效

,换句话说RestTemplate如果要使用Fastjson还是要对RestTemplate进行额外配置,而不是在SpringBoot项目里配置了类型是HttpMessageConverters的Bean就可以了;

方式可以参考:https://www.jianshu.com/p/c9644755dd5e

一:没有泛型的情况(这里以POST举例,但是对于GET也是一样的)

CommonResponse response = restTemplate.postForObject(remoteUrl, tokenRequest, CommonResponse.class);

这里tokenRequest是请求体对象,将会由Fastjson序列化为JSON字符串,它所属的类无所谓是不是有泛型,因为可以通过member.getClass()获得(即tokenRequest中所有的成员的类型是确立的且可获取的);

使用的时候最好用restTemplate.postForEntity()的而不要用restTemplate.postForObject(),后者不能设置Header,而且似乎也不能执行Multipart请求;

二:有泛型的情况

CommonResponse<TokenDataModel> response = restTemplate.postForObject(remoteUrl, tokenRequest, CommonResponse.class);

这个时候就有问题了,因为CommonResponse在字节码里是泛型擦除的,它所有的泛型成员本质上就是一个Object类型的子类但是.class里没有记录到底是什么具体类,因此当获取的response的JSON字符串中:

{
"code": 8209,
"code_description": "APPLICANT_SUCCESS",
"data": {
"cell_phone_number": "1111111111",
"collect_website": "中国联通","token": "77785fb276ed47cb9a01ec52f9a133c8"
},
"message": "成功"
}

将data部分转换为泛型成员时RestTemplate将不知道该怎么转换,如果将T类型认为是Object,那么显然Object是没有cellPhoneNumber之类的属性的,所以RestTemplate的做法是将data部分的JSON字符串转换为了LinkedHashMap对象(key-value对);

三:解决方式

通过RestTemplate的exchange方法来解决:

ParameterizedTypeReference<CommonResponse<TokenDataModel>> typeRef = new ParameterizedTypeReference<CommonResponse<TokenDataModel>>() {};
// exchange并不对应于任何一种method,如GET、POST、PUT、DELETE,因此需要手动指定
CommonResponse<TokenDataModel> response = restTemplate.exchange(remoteUrl, HttpMethod.POST, new HttpEntity<>(tokenRequest), typeRef).getBody();

四:单纯用Fastjson转换有泛型的类的方式

CommonResponse<TokenDataModel> response = JSON.parseObject("{json string}", new com.alibaba.fastjson.TypeReference<CommonResponse<TokenDataModel>>(){});

五:原理

在java里,泛型类编译成.class后确实是泛型擦除,但是泛型类对象里是会(间接)存储泛型的实际类型的,因此需要new TypeReference<Test<RealType>>(){}产生一个对象;

它内部是:

// 获取匿名类对象的Generic父类,即Test<RealType>类型
// 注意superClass并不是Class类对象,它应该理解为:
// 为泛型类的子匿名类对象产生的一个与之一一对应的Type类对象(这个倒像真泛型)
// 这个Type类对象里存储了此匿名类对象的所有泛型信息
Type superClass = getClass().getGenericSuperclass();

最新文章

  1. Android ButterKnife配置使用
  2. (AIDE)Android Eclipse JNI 调用 .so文件加载问题
  3. feedback 是什么意思
  4. curl返回值写入内存的场景
  5. [置顶] ffmpg简介以及用它实现音频视频合并(java)
  6. C++ Primer 学习笔记_29_STL实践与分析(3) --操作步骤集装箱(下一个)
  7. Java 集合的理解(持续更新......)
  8. Node.js编写CLI的实践
  9. 六一儿童节PHP宝宝又被围剿了,迅速围观!
  10. 用开源的 ffmpeg 实现屏幕录像机
  11. Linux基本命令总结(六)
  12. FastReport预览后直接邮件发送
  13. vue版 文件下载
  14. css 中 position属性
  15. thymeleaf(一)
  16. **CI中创建你自己的类库
  17. Nokia 920全部CODE
  18. mov指令
  19. Python学习之路:NumPy进阶
  20. bzoj1211: [HNOI2004]树的计数 prufer编码

热门文章

  1. java_13.1 javaAPI
  2. 永久激活win和office
  3. 内置函数 hashlib configparser logging 模块 C/S B/S架构
  4. 关于RNA-Seq数据去接头(Adapter)这事需要讲一讲
  5. c++文件的输入输出
  6. 字符串匹配 - sunday算法
  7. JDK8集合类源码解析 - HashMap
  8. 连接db2数据库出现No buffer space available (maximum connections reached?)
  9. 一台老服务器的升级日志(PHP4.4.9+MySQL5.1)升级MySQL5.6
  10. AX_Args