ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring Boot应用的Controller返回的集合类数据是XML格式的可能原因

2020-07-11 13:37:46  阅读:227  来源: 互联网

标签:XML xml jackson Spring Boot JSON fastJsonConverter 转换器


  今天使用Eureka Client的时候发现Controller打了@RestController注解,对于返回值是集合类的API接口,其数据还是会被系列化成XML格式:

    @GetMapping("/user-instance")
    public List<ServiceInstance> showUserServiceInfo() {
        return this.discoveryClient.getInstances("provider-user-metadata");
    }

  结果:

<List>
    <item>
        <scheme>http</scheme>
        <host>192.168.0.102</host>
        <port>8000</port>
        <metadata>
            <author>xurm</author>
            <management.port>8000</management.port>
            <age>26</age>
        </metadata>
    </item>
</List>

  经过排查发现是spring-cloud-starter-netflix-eureka-client的Maven依赖间接引入了jackson-dataformat-xml包,而如果Spring的http消息转换器(HttpMessageConverter)使用了该包会,那么它会根据http请求头上的Accept来决定返回XML还是JSON。然而目前大多数浏览器在没有额外设置的情况下,默认的Accept值都是"text/html,application/xhtml+xml,application/xml",这就使得直接在浏览地址栏访问接口时,预期要返回JSON的返回了XML,因为JSON和XML格式是可以互转的!

  但是如今应用开发使用JSON方便一些,特别是与前端数据交换的时候,可以直接用上JS与JSON的无缝对接优势,所以得把返回值改成JSON才行,方法有多种,这里介绍两种:

  第一种是:如果你的应用不会再需要返回xml的系列化格式,那么直接在pom.xml文件中将jackson-dataformat-xml这外包排除即可(如果其他包也进行了jackson-dataformat-xml的依赖引用也要视情况排除):

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.3.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.dataformat</groupId>
                    <artifactId>jackson-dataformat-xml</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

  刷新maven,重新启动应用,再次访问相应接口:

[{
    "scheme": "http",
    "host": "192.168.0.102",
    "port": 8000,
    "secure": false,
    "metadata": {
        "author": "xurm",
        "management.port": "8000",
        "age": "26"
    }
}]

  第二种是:不排除jackson-dataformat-xml包,而是直接在相应接口方法上明确指定将返回JSON格式的值:

    @GetMapping(value = "/user-instance", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
    public List<ServiceInstance> showUserServiceInfo() {
        return this.discoveryClient.getInstances("provider-user-metadata");
    }

 

  从上面的问题原理可知:项目里一个接口是可以同时支持返回XML和JSON的,只要在Accept中声明你要XML还是要JSON。当然也有借助第三方包(jackson-jaxrs-xml-provider),然后通过URL后缀是*.json还是*.xml来返回JSON还是XML的做法!只是此时就不能再在接口方法上明确指定将返回什么格式的值了:

    @GetMapping(value = "/user-instance")
    public List<ServiceInstance> showUserServiceInfo() {
        return this.discoveryClient.getInstances("provider-user-metadata");
    }

 

  最后,其实还可以通过添加自定义的Spring的http消息转换器(HttpMessageConverter)的方法来定制返回值的系列化,方法就是实现WebMvcConfigurer,并重写configureMessageConverters方法,例如换用阿里的Fastjson来做http消息转换:

    /**
     * 消息转换器自定义配置,向当前的Http消息转换器列表增加阿里云的FastJson消息转换器
     *
     * @param converters 当前的Http消息转换器列表对象
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        fastJsonConverter.setFastJsonConfig(fastJsonConfig);
        //converters.add(fastJsonConverter);//这会让fastJsonConverter排在消息转换器管道列表的最后,可能会轮不到它处理消息转换
        converters.add(0, fastJsonConverter);//要显示指明将fastJsonConverter排在消息转换器管道列表的首位
    }

  pom.xml中引入Fastjson的依赖:

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>

 

标签:XML,xml,jackson,Spring,Boot,JSON,fastJsonConverter,转换器
来源: https://www.cnblogs.com/xuruiming/p/13283288.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有