源码解析-为什么引入了jackson-dataformat-xml 包我的接口全变成了xml格式?

article/2025/1/17 3:03:52

本文从引入jackson-dataformat-xml 之后接口全变成xml 现象开始,一步步排查代码原因,并提出解决方案。希望能对遇到相关问题的人有所帮助

新调用上游一个接口,增加了对方的一个api包,没修改任何逻辑,接口却从json返回全变成了xml格式?
原接口:
在这里插入图片描述

现在:
在这里插入图片描述

排查之后定位到是因为对方的api包里增加了一个依赖包

<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.9.7</version>
</dependency>

那这个包是怎么生效的呢?
需要从spring-mvc 说起
当我们的代码里这么写的时候
在这里插入图片描述

spring-mvc 的执行流程:

SpringMVC执行流程:

1.用户发送请求至前端控制器DispatcherServlet
2.DispatcherServlet收到请求调用处理器映射器HandlerMapping。
3.处理器映射器根据请求url找到具体的处理器,生成处理器执行链HandlerExecutionChain(包括处理器对象和处理器拦截器)一并返回给DispatcherServlet。
4.DispatcherServlet根据处理器Handler获取处理器适配器HandlerAdapter执行HandlerAdapter处理一系列的操作,如:参数封装,数据格式转换,数据验证等操作
5.执行处理器Handler(Controller,也叫页面控制器)。
6.Handler执行完成返回ModelAndView
7.HandlerAdapter将Handler执行结果ModelAndView返回到DispatcherServlet
8.DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9.ViewReslover解析后返回具体View
10.DispatcherServlet对View进行渲染视图(即将模型数据model填充至视图中)。
11.DispatcherServlet响应用户。

其中第9步骤里,ViewReslover解析后返回具体View 。
这里在找对应的解析器的时候有这样一步 第381行:
在这里插入图片描述

我们看到在getDefaultMediaTypes() 这里
在这里插入图片描述
在这里插入图片描述
就恍然大悟了。spring-webmvc里 已经有写好的判断是否有当前类 如果有作为一个可处理的类型放在map里,而恰好xml 在json之前

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

那么有什么办法 避免引入这个包之后就变成了xml么?如果能排除当然可以排除这个包,但是仍然无法避免下次其他依赖包里是否有对应的依赖,并且也无法排除你的项目里真的不会遇到这个包。那么怎么样可以避免呢?

其实答案就在上边的这个图里,看下方法 writeWithMessageConvert 的逻辑

protected <T> void writeWithMessageConverters(T returnValue, MethodParameter returnType,  ServletServerHttpRequest inputMessage, ServletServerHttpResponse outputMessage)  throws IOException, HttpMediaTypeNotAcceptableException {  Class<?> returnValueClass = returnValue.getClass();  HttpServletRequest servletRequest = inputMessage.getServletRequest();  
//获取客户端Accept字段接收的content-type  List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(servletRequest);  
//获取服务器端指定的content-type,如果@RequestMapping中的produces配置了content-type,则返回此content-type,若果没有,
则获取所有HttpMessageConverter所支持的content-type,然后通过requestedMediaTypes和producibleMediaTypes 对比,选定一个最合适的content-type作为  
//selectedMediaType  List<MediaType> producibleMediaTypes = getProducibleMediaTypes(servletRequest, returnValueClass);  Set<MediaType> compatibleMediaTypes = new LinkedHashSet<MediaType>();  for (MediaType requestedType : requestedMediaTypes) {  for (MediaType producibleType : producibleMediaTypes) {  if (requestedType.isCompatibleWith(producibleType)) {  compatibleMediaTypes.add(getMostSpecificMediaType(requestedType, producibleType));  }  }  }  if (compatibleMediaTypes.isEmpty()) {  throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);  }  List<MediaType> mediaTypes = new ArrayList<MediaType>(compatibleMediaTypes);  MediaType.sortBySpecificityAndQuality(mediaTypes);  MediaType selectedMediaType = null;  for (MediaType mediaType : mediaTypes) {  if (mediaType.isConcrete()) {  selectedMediaType = mediaType;  break;  }  else if (mediaType.equals(MediaType.ALL) || mediaType.equals(MEDIA_TYPE_APPLICATION)) {  selectedMediaType = MediaType.APPLICATION_OCTET_STREAM;  break;  }  }  if (selectedMediaType != null) {  selectedMediaType = selectedMediaType.removeQualityValue();  for (HttpMessageConverter<?> messageConverter :   
//遍历所有已注册的HttpMessageConverter,选出一个支持返回值类型returnValueClass和  
//selectedMediaType的HttpMessageConverter来进行写入数据到response的body中。  
this.messageConverters) {  if (messageConverter.canWrite(returnValueClass, selectedMediaType)) {  ((HttpMessageConverter<T>) messageConverter).write(returnValue, selectedMediaType, outputMessage);  if (logger.isDebugEnabled()) {  logger.debug("Written [" + returnValue + "] as \"" + selectedMediaType + "\" using [" +  messageConverter + "]");  }  return;  }  }  }  throw new HttpMediaTypeNotAcceptableException(this.allSupportedMediaTypes);  }  

所以 比较安全的解决办法是:
1) 提供方法时,我们可以指定方法的返回类型
例如: @RequestMapping(value ="/test",produces=“application/json”) 中 produces 可以指定方法对应的类型等

2) 请求方法时,我们可以指定想要的返回类型
例如:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/otkTAJrq.shtml

相关文章

Java-常用API(StringBuffer,Math,Date,DataFormat,Calender,Runtime,System,包装类)

Java常用API StringBuffer 为了解决String字符串操作导致的内存冗余&#xff0c;提高效率&#xff0c;Java中提供了StringBuffer和StringBuilder来操作字符串&#xff0c;并且提供了很多方法&#xff0c;便于程序员开发 StringBuffer和StringBuilder中都有char类型可变长数组…

Java知识点--DataFormat,SimpleDateFormat和DateTimeFormatter

Java知识点–DataFormat&#xff0c;SimpleDateFormat和DateTimeFormatter 这个知识点没什么难懂的地方&#xff0c;就不一一赘述了。 import java.text.DateFormat; import java.util.Date; import java.util.Locale;public class test01 {public static void main(String[]…

04、添加 com.fasterxml.jackson.dataformat -- jackson-dataformat-xml 依赖报错

Correct the classpath of your application so that it contains a single, compatible version of com.fasterxml.jackson.dataformat.xml.XmlMapper 解决&#xff1a; 改用其他版本&#xff0c;我没写版本号&#xff0c;springboot自己默认的是 2.11.4 版本 成功启动项目…

Excel表格样式CellStyle的DataFormat可选值

Excel表格样式CellStyle的DataFormat可选值 干啥子遇到的问题DataFormat可选项源码查看出处1、访问https://poi.apache.org/apidocs/4.1/ ,全局搜索CellStyle2、找到其对应的类-BuiltinFormats 干啥子 解决表格样式的设置&#xff0c;找到DataFormat可选值。 遇到的问题 在使…

java中的Date类,DataFormat类及Calendar类的使用详解

Date类的构造方法 Date类拥有多个构造函数&#xff0c;只是部分已经过时&#xff0c;但是其中有未过时的构造函数可以把毫秒值转成日期对象。 /* * Date类的long参数的构造方法 * Date(long ) 表示毫秒值 * 传递毫秒值,将毫秒值转成对应的日期对象 * 结果为…

Java 常用类Data和Format类 使用教程

一、Date类使用方法。 1. new Date() 返回当前时间 Date date new Date(); System.out.println(date);//输出当前的时间。源码解释为&#xff1a; 2. new Date(10006060*24); 返回 从 Fri Jan 01 08:00:00 CST 1970经过1天的时间 long time 1000*60*60*24; Date date n…

矩阵按键行列反转扫描法

51单片机 | 矩阵键盘行扫描 ———————————————————————————————————————————— 分类&#xff1a; 按结构原理分&#xff1a; 触点式开关按键无触点开关按键 接入方式 独立式按键矩阵式键盘 ———————————————————…

基于GD32矩阵按键程序实现

目录 一、简介 二、原理图 三、程序实现 一、简介 矩阵键盘&#xff0c;也称矩阵按键&#xff0c;是为了节约单片机IO口占用所引入的一种外设。 二、矩阵按键的原理图 三、程序实现 GPIO初始化引脚代码 /*!\brief Init Key Function\param[in] none\param[out] non…

4、按键(独立/矩阵按键)

一、 独立按键原理 按键在闭合和断开时&#xff0c;触点会存在抖动现象。 PS:定义小灯时&#xff0c;如果定义为#define led P2&#xff0c;这样按下K1时八个灯就会同时熄灭或点亮&#xff0c;&#xff0c;当然&#xff0c;如果要其中几个灯点亮&#xff0c;就分别定义…

蓝桥杯单片机 独立按键与矩阵按键

文章目录 前言一、蓝桥杯按键原理图二、独立按键与矩阵按键处理思路 1.独立按键2.矩阵按键代码实现总结 前言 按键设计一般分为两种&#xff1a;独立按键和矩阵键盘。按键数量较少的用前者&#xff0c;按键数量较多的用后者。虽然两种设计都是操作按键&#xff0c;但是其键盘扫…

单片机STM32入门——(3)矩阵按键

单片机STM32入门——&#xff08;3&#xff09;矩阵按键 1.理论分析1.1键盘扫描方式1.2行扫描逻辑1.3列扫描逻辑 2.程序编写2.1按键扫描程序2.1.1按键初始化2.1.2按键扫描程序头文件2.1.3行扫描函数2.1.3列扫描函数 2.2主程序 1.理论分析 1.1键盘扫描方式 我们所用到的键盘为…

51单片机之按键(独立按键矩阵按键)

难的东西学不会是因为简单的知识没学好 基础不牢&#xff0c;地动山摇 按键 1.1基础温习 &#xff08;1&#xff09;按键的物理结构 &#xff08;2&#xff09;单片机引脚有两种状态&#xff08;I/O&#xff09;输入【读】或者输出【写】 &#xff08;3&#xff09;上拉电阻…

51学习-矩阵按键篇

使用并行接口方式连接键盘&#xff0c;对独立式键盘而言&#xff0c;8根I/O口线可以接 **8** 个按键&#xff0c;而对矩阵式键盘而言&#xff0c;8根I/O口线最多可以接 **64** 个按键。 项目(工程)的时候&#xff0c;我们经常要用到比较多的按键&#xff0c;而且IO资源紧张&am…

4x4矩阵按键应用详解

一.简介 4x4矩阵按键是单片机外部设备中所使用的排布类似于矩阵的按键组。显然矩阵按键的使用要比独立按键要复杂一些&#xff0c;编程也要复杂一些&#xff0c;但可以单片机IO资源。4x4矩阵按键即分为4组列线&#xff0c;4组行线&#xff0c;并将行线所接的单片机的I/O口作为…

独立按键和矩阵按键c语言,第八章 独立按键和矩阵按键

我们和单片机之间进行信息交互,主要包含两大类,输入设备和输出设备。前边讲的LED小灯、数码管、点阵都是输出设备,这节课我们学习一下最常用的输入设备——按键。在本节课的学习过程中我们还会穿插介绍一点硬件设计的基础知识。 8.1单片机最小系统电路解析 8.1.1电源 我们在…

单片机 矩阵式按键

单片机 矩阵式按键 一、简述 在单片机应用系统中&#xff0c;通过按键实现数据输入及功能控制是非常普遍的&#xff0c;通常在所需按键数量不多时&#xff0c;系统常采用独立式按键。需要按键数量比较多&#xff0c;为了减少I/O口的占用&#xff0c;通常将按键排列成矩阵。测…

矩阵按键原理和BUG

当我们的电路有很多按键时&#xff0c;一般会采用矩阵方式与单片机相连来减少对单片机IO的浪费&#xff0c;如下图方式。 这个电路的原理: 1、比如检测S13是否按下&#xff0c;单片机把Line4设为输出&#xff0c;并输出低电平&#xff0c;而Line3、Line2、Line1设为开路输入&…

关于矩阵按键

前段时间老师讲了矩阵按键&#xff0c;就把程序的理解写下来 看图片&#xff0c;只有主函数和串口。串口在此用来发送我们的按键值&#xff0c;波特率9600&#xff0c;频率11.0592。 我们用的是4*4矩阵按键 我们的矩阵按键连在了单片机的P0口&#xff08;stc15f2k60s2&#xf…

独立按键和矩阵按键c语言,单片机独立按键与矩阵按键原理图

当前位置:电工之家 > 电工知识 > 单片机 > 正文 单片机独立按键与矩阵按键原理图 时间:2017-02-22 12:40 来源:电工之家 单片机独立按键与矩阵按键原理图 独立按键 通常的按键分为独立式按键和矩阵式按键两种,独立式按键比较简单,并且与独立的输入线相连接,如图13…

【按键扫描】矩阵按键之多按键扫描

前言 上一章我们介绍了经典矩阵键盘的实现方法&#xff0c;但是示例程序中仅实现了单按键检测功能。虽说单按键已经基本可以覆盖矩阵键盘的常见需求&#xff0c;但在一些特殊应用场合&#xff0c;我们仍然需要多按键识别操作&#xff0c;或者一些类似电脑组合按键的功能支持。…