無味
发布于 2024-04-29 / 13 阅读
0

RestTemplate突然变成xml结果了

RestTempate访问某天突然从json的结果变成xml,导致线上许多远程调用解析失败

如图:

查询原因:

RestTemplate初始化源码:

    static {
        ClassLoader classLoader = RestTemplate.class.getClassLoader();
        romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader);
        jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
        jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
        jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
        jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
        jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);
        gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
        jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader);
        kotlinSerializationJsonPresent = ClassUtils.isPresent("kotlinx.serialization.json.Json", classLoader);
    }

其中jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);检测到时会自动加入到解析结果中

此时:如果第三方接口没有指定默认resource类型,则默认解析会转成xml格式。

那么为社么突然会转成xml?

跟踪上述XmlMapper类. 指向->"jackson-dataformat-xml.jar". 进一步跟踪,为前段时间新导入的第三方jar依赖了进来

解决方案:

  1. 在依赖jar中进行jar排除可以解决


            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.dataformat</groupId>
                    <artifactId>jackson-dataformat-xml</artifactId>
                </exclusion>
            </exclusions>

  1. 在创建RestTemplate时重置转换对象

根据源码查看加入位置:

    public RestTemplate() {
        ....
        if (!shouldIgnoreXml) {
            if (jackson2XmlPresent) {
                this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
            } else if (jaxb2Present) {
                this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
            }
        }
        .....

那么,重置messageConverters 也就能解决问题;
重置方法setMessageConverters:

        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setMessageConverters(Lists.newArrayList(new FastJsonHttpMessageConverter()));

End