一、需求场景:

有个需求场景:同一个请求路径,入参类型分别有“JSON格式”和“XML格式”的入参,需要根据入参类型的不同,处理不同的业务场景,然后返回对应格式的返回。值。比如:

​ JSON格式入参,返回JSON格式的返回值。

​ XML格式入参,返回XML格式的返回值。

印象中是可以区分的,然后网上搜索了资料完善了解决方案,好记性不如烂笔头,现在梳理一下如下:

二、解决方案

第一种方案:SpringMvc 自定义 XML的 HttpMessageConverter 转换器。

自定义转换器的方式本身没有问题,自己写一个 继承 ObjectMapper 类的xmlMapper就能实现。一开始我是用的这个,后来发现这样写很多余,因为 ObjectMapper 我是引用了"com.fasterxml.jackson.dataformat.xml.XmlMapper" ,实际上完全可以不用自己写,原因是 :如果引入了"com.fasterxml.jackson.dataformat.xml.XmlMapper"依赖,SpringMVC会自动加载XML转换器,优先级是XML优先。更优的办法详见第二种方式。

import java.util.List;import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import com.fasterxml.jackson.dataformat.xml.XmlMapper;@Configuration
public class WebConfiguration implements WebMvcConfigurer {/*** 新增自定义转换器* @param converters {@link List<HttpMessageConverter<?>>}*/@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {MappingJackson2XmlHttpMessageConverter xmlConverter = new MappingJackson2XmlHttpMessageConverter();XmlMapper xmlMapper = new XmlMapper();xmlConverter.setObjectMapper(xmlMapper);//新增 xml转换器,设置顺序为0converters.add(0,xmlConverter);}
}

第二种方案:直接引入XML 转换器的依赖

SpringBoot项目,可以在 Pom.xml 中直接引入**" jackson-dataformat-xml"** 依赖。

<!-- Springboot默认使用json格式解析参数,如果需要支持xml入参,则需要引入 'jackson-dataformat-xml'依赖 -->
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><!-- 注意版本应该与 Springboot版本匹配。看SpringBoot版本发布日期去Maven找对应的版本号 --><version>${jackson-dataformat-xml.version}</version>
</dependency>

定义同一个名为"/test"的请求,通过指定“consumes” 和“produces”属性区分JSON格式和XML格式的控制,注意方法名要不一样。

      /*** 示例:* 接收JSON格式的入参,并返回JSON格式的返回值* consumes:指入参的 MediaType类型,这里设置为:接收UTF-8的JSON格式,* produces:指返回值的MediaType类型,这里设置为:返回UTF-8的JSON格式。*/@PostMapping(value = "/test",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,produces = MediaType.APPLICATION_JSON_UTF8_VALUE)public JSONObject Json(@RequestBody JSONObject requestJsonObject) {//业务代码,略}/*** 示例:* 接收XML格式的入参,并返回XML格式的返回值* consumes:指入参的 MediaType类型,这里设置为:接收XML格式,* produces:指返回值的MediaType类型,这里设置为:返回XML格式。*/@PostMapping(value = "/test",consumes = MediaType.APPLICATION_XML_VALUE,produces = MediaType.APPLICATION_XML_VALUE)public JSONObject Xml(@RequestBody JSONObject requestJsonObject) {//业务代码,略}

三、源码分析:SpringMVC ,默认的设置的 MediaType的顺序

public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {private static final boolean romePresent =ClassUtils.isPresent("com.rometools.rome.feed.WireFeed",WebMvcConfigurationSupport.class.getClassLoader());private static final boolean jaxb2Present =ClassUtils.isPresent("javax.xml.bind.Binder",WebMvcConfigurationSupport.class.getClassLoader());private static final boolean jackson2Present =ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",WebMvcConfigurationSupport.class.getClassLoader()) &&ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",WebMvcConfigurationSupport.class.getClassLoader());private static final boolean jackson2XmlPresent =ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper",WebMvcConfigurationSupport.class.getClassLoader());private static final boolean jackson2SmilePresent =ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory",WebMvcConfigurationSupport.class.getClassLoader());private static final boolean jackson2CborPresent =ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory",WebMvcConfigurationSupport.class.getClassLoader());private static final boolean gsonPresent =ClassUtils.isPresent("com.google.gson.Gson",WebMvcConfigurationSupport.class.getClassLoader());private static final boolean jsonbPresent =ClassUtils.isPresent("javax.json.bind.Jsonb",WebMvcConfigurationSupport.class.getClassLoader());protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();stringHttpMessageConverter.setWriteAcceptCharset(false);  // see SPR-7316messageConverters.add(new ByteArrayHttpMessageConverter());messageConverters.add(stringHttpMessageConverter);messageConverters.add(new ResourceHttpMessageConverter());messageConverters.add(new ResourceRegionHttpMessageConverter());messageConverters.add(new SourceHttpMessageConverter<>());messageConverters.add(new AllEncompassingFormHttpMessageConverter());if (romePresent) {messageConverters.add(new AtomFeedHttpMessageConverter());messageConverters.add(new RssChannelHttpMessageConverter());}if (jackson2XmlPresent) {Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();if (this.applicationContext != null) {builder.applicationContext(this.applicationContext);}// 新增 XML 转换器messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));}else if (jaxb2Present) {messageConverters.add(new Jaxb2RootElementHttpMessageConverter());}if (jackson2Present) {Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();if (this.applicationContext != null) {builder.applicationContext(this.applicationContext);}// 新增 JSON 转换器messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));}else if (gsonPresent) {// 新增 Gson 转换器messageConverters.add(new GsonHttpMessageConverter());}else if (jsonbPresent) {// 新增 Jsonb 转换器messageConverters.add(new JsonbHttpMessageConverter());}if (jackson2SmilePresent) {Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.smile();if (this.applicationContext != null) {builder.applicationContext(this.applicationContext);}//新增 Smile 转换器messageConverters.add(new MappingJackson2SmileHttpMessageConverter(builder.build()));}if (jackson2CborPresent) {Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.cbor();if (this.applicationContext != null) {builder.applicationContext(this.applicationContext);}//新增 Cbor 转换器messageConverters.add(new MappingJackson2CborHttpMessageConverter(builder.build()));}}
}

从源码看,导入了对应的依赖,比如 “jackson-dataformat-xml” ,依赖包会有 "com.fasterxml.jackson.dataformat.xml.XmlMapper"类被SpringMVC找到,

然后就会自动加到 messageConverters 转换器中,顺序就是代码add的顺序, XML > Json > Gson > Jsonb > Smile > Cbor

参考网站

SpringBoot项目 整合 JacksonXml相关推荐

  1. Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数Demo

    Docker 部署SpringBoot项目整合 Redis 镜像做访问计数Demo 最终效果如下 大概就几个步骤 1.安装 Docker CE 2.运行 Redis 镜像 3.Java 环境准备 4. ...

  2. springboot项目整合mybatis

    SpringBoot项目整合mybatis 本章内容 使用 idea创建 SpringBoot项目 SpringBoot项目中配制 mybatis 框架 1 创建 SpringBoot项目 1.1 在 ...

  3. springboot项目整合阿里云oss的内容审核

    springboot项目整合阿里云 内容审核 第一 添加依赖 <dependency><groupId>com.aliyun</groupId><artifa ...

  4. Java springBoot项目整合海康威视摄像头抓拍车辆功能

    Java springBoot项目整合海康威视摄像头抓拍获取车辆信息功能 这篇文字写于去年的11月份,项目部署上去一段时间后,被反应有自动停止抓拍的BUG,我在代码中的解决办法是写了一个定时任务, 让 ...

  5. SpringBoot项目整合OpenFeign、实现动态IP+URL请求、自定义(编码器\解码器)

    SpringBoot项目整合OpenFeign 基础操作 pom依赖 配置application.yml 服务启动类 基础跨服务调用 动态IP+URL请求 + 动态编码器\解码器 自定义跨服务请求,E ...

  6. Nginx安装配置与SpringBoot项目整合

    本篇文章将在上篇<Redis安装与SpringBoot项目整合详细教程>(上文链接:https://blog.csdn.net/sp958831205/article/details/88 ...

  7. SpringBoot项目整合Retrofit最佳实践,这才是最优雅的HTTP客户端工具!

    作者:六点半起床 juejin.im/post/6854573211426750472 大家都知道okhttp是一款由square公司开源的java版本http客户端工具.实际上,square公司还开 ...

  8. spring-boot项目整合obs服务器-华为云

    目录 前言 1.购买服务并从官网获得我们项目所需的配置参数 1-1.登录华为云 1-2.进入控制台 1-3.创建桶 ​ ​1-4.获取sk.ak 2.spring-boot项目集成OBS服务器 2-1 ...

  9. RabbitMQ的6种工作模式的学习记录,普通MAVEN和springboot项目整合rabbitmq的API详解

    1.RabbitMQ后台管理页面 2.RabbitMQ 核心(自我理解) 3.RabbitMQ6种工作模式介绍 4. RabbitMQ的消息可靠性 5.RabbitMQ普通MAVEN项目使用 6.Sp ...

最新文章

  1. Django博客系统(文章分类模型)
  2. 生物学专业_北京交通大学617生物化学20082011历年考研专业课真题汇编
  3. java 基本类型之间的转换
  4. php扫描蓝牙设备接口,微信硬件蓝牙扫描某个设备接口onScanWXDeviceResult
  5. find_first_of()和 find_last_of() 【获取路径、文件名】
  6. jquery-1.10.2.min.map是什么,怎么用?
  7. 【Python】输入任意个数元素并保存至列表
  8. 9600kf功耗和温度评测_i5-9400F与i5-9600KF性能差距大吗?i5 9600KF和9400F区别对比
  9. 【最短路径】之Dijkstra算法
  10. html ul标签宽度,css - ul中每个li的不同宽度 - SO中文参考 - www.soinside.com
  11. 分布式智能微电网的体系结构操作系统
  12. 如何从产品和技术角度上做一个好产品----软件公司如何开源节流(二)
  13. pdf格式如何压缩文件大小?
  14. 【大咖周刊】Linus 在谷歌介绍 Git、IBM340亿收购小红帽、IDE Visual Studio 开始支持 Java 了...
  15. 联想个人云 X1 五盘位NAS全网首发评测 值得买吗?
  16. C语言实现扫雷小游戏 纯小白 非黑窗口
  17. C/C++ 实验设备管理系统
  18. 未来链上跨境支付、融资领域龙头 Tribal 的发展与机遇
  19. Git 命令行的各种退出方式
  20. 渝粤题库 陕西师范大学《西方文论》作业

热门文章

  1. 【hdu4010】 Query on The Trees
  2. 大道至简读后感(七八章)
  3. 三种banner基础形态
  4. 手把手教你使用Pandas读取结构化数据
  5. 盘点数据科学最流行的29个Python库
  6. 【知识】人工智能数学基础知识
  7. 在计算机网络中为了保证正确传输,计算机网络试卷B
  8. angular自带的一些api_Angular API
  9. 看了5种分布式事务方案,最终选择了Seata,真香!
  10. 线程切换是如何给 CPU 洗脑的?