RestTemplate响应结果转换

背景

对接一个关联系统,使用SpringBoot中的RestTemplate调用关联方,对方返回的结果是josn格式,如下:

json 复制代码
{
  "Code":"0",
  "Result":{
    "Count":297663
  }
}

即他们的json是用大写字母开头的。如果直接使用restTemplate.exchange(url, HttpMethod.POST, requestEntity, RsponseData.class).getBody();,得到的结果(RsponseData)中的字段都是空的,RsponseData中的字段如下:

java 复制代码
public class RsponseData<T> {
    private String code;
    private T result;
}

问题分析

在java中,我们定义字段的时候,规范化的做法一般是小写字母开头,驼峰命令。但是对方给出这种json格式,不能说是不规范的,只要能统一就行(每个接口的响应格式规范都不一样,就是坑了)。 如果我们想接收这种大写字母开头的json字符串,把RsponseData中的字段改为大写开头,结果还是会接收不到。

解决方案

有多种方式,根据具体情况采取:

字符串接收,再转换

在使用restTemplate.exchange的时候,我们是直接给了RsponseData.class,如果使用String.class,那么就可以得到这个json字符串。拿到json字符串之后,再手动将该字符串转为RsponseData对象。将json字符串转为对象的方法有很多,这里就不赘述了。 此种方式,兼容性好,但封装性不强,不够优雅。但隔离性好,不影响其他接口。

使用@JsonProperty

之所以无法转换,无非就是jackson在处理映射的时候,是大小写敏感的,所以,通过@JsonProperty,指定他们映射关系即可:

java 复制代码
public class NbBsicResponse<T> {
    @JsonProperty("Code")
    private String code;
    @JsonProperty("Result")
    private T result;
}

如果有很多个字段,那么这个注解就要写很多了,同样,隔离性也很好,不影响其他接口。

修改RestTemplate的配置

在配置resteTemplate的时候,修改它处理json的配置,具体如下:

java 复制代码
    @Bean("xxxcRestTemplate")
    public RestTemplate buildRestTemplate() {
        // 创建一个ObjectMapper实例
        ObjectMapper objectMapper = new ObjectMapper();
        // 配置ObjectMapper忽略JSON键名的大写字母开头
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        //不要试图自己创建一个converter,因为自动配置中的,会有其他的配置,自己弄,配置不全,还不如遍历已有的,然后修改自己想要修改的
        // 创建一个使用配置好的ObjectMapper的HttpMessageConverter
//        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//        converter.setObjectMapper(objectMapper);
//        converter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_HTML));

        // 将HttpMessageConverter加入到RestTemplate的消息转换器列表中
        RestTemplate restTemplate = new RestTemplate();
        for (HttpMessageConverter<?> messageConverter : restTemplate.getMessageConverters()) {
            if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
                ((MappingJackson2HttpMessageConverter) messageConverter).setObjectMapper(objectMapper);
            }
        }
        return restTemplate;
    }

这种方式,封装性就很好了。但通常来说,每个对接的系统,都应该单独配置一个RestTemplate,设置一些公共参数以及配置;但如果有些同一个系统,提供的接口规范不一致,那么就得对单独的接口进行配置RestTemplate。如果遇到更奇葩的:同一个接口中,不同节点的规范都不一样,那么就得配合@JsonProperty来处理了。

相关推荐
计算机毕设指导6几秒前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
Gu Gu Study2 分钟前
枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~
java·开发语言
Chris _data5 分钟前
二叉树oj题解析
java·数据结构
牙牙70510 分钟前
Centos7安装Jenkins脚本一键部署
java·servlet·jenkins
paopaokaka_luck18 分钟前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
以后不吃煲仔饭30 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师31 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
The_Ticker37 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法