请求转换为XML格式 jaskson-dataformat 依赖相关

  • 背景:

项目引入jackson-dataformat-xml 依赖

问题:

请求失败。发现请求的响应格式变为XML。

分析:

1. 请求时,Accept 头为 “application/xml, text/xml, application/*+xml, */*” 与HTTP 的Content Negotiation 有关 https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation
2. spring DispatcherServlet 按照Accept header 对返回类型的处理

对于这个问题,我们关注第7步,返回MAV时对结果格式的转换(偷了图)


DispacherServlet.doDispatch

2、3 对应 :1023行
4、5、6、7 对应 :1040行 、执行handle 返回结果时,会根据Accept header 对返回类型进行转换

1. 响应返回类型的决定 

AbstractMessageConverterMethodProcessor.writeWithMessageConverters 234行

 

  1. acceptableTypes 请求accept header 里要求的类型 

  2. producibleTypes 服务器可以产生的类型

2. 源码

org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters(T, org.springframework.core.MethodParameter, org.springframework.http.server.ServletServerHttpRequest, org.springframework.http.server.ServletServerHttpResponse)
 

解决办法:

1. 显式请求Accept头 为"*/*"
2. RequestMapping 设置produce 属性
produces = {"application/json; charset=UTF-8"}

3.设置默认返回内容类型 见: https://www.cnblogs.com/weilu2/p/springmvc_controller_handler_return_json_xml.html

想法:

1. 为什么Accept 含有xml ?可能restTemplate默认设置,与依赖版本有关 https://blog.csdn.net/blowbob_666/article/details/112250864

2. 默认Accept 传 "*/*"时为什么默认选json? 

org.springframework.boot.autoconfigure.http.HttpMessageConverters 37行

this.getCombinedConverters(converters, addDefaultConverters ? this.getDefaultConverters() : Collections.emptyList());
private List<HttpMessageConverter<?>> getDefaultConverters() {
List<HttpMessageConverter<?>> converters = new ArrayList();
if (ClassUtils.isPresent("org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport", (ClassLoader)null)) {
converters.addAll((new WebMvcConfigurationSupport() {
public List<HttpMessageConverter<?>> defaultMessageConverters() {
return super.getMessageConverters();
}
}).defaultMessageConverters());
} else {
converters.addAll((new RestTemplate()).getMessageConverters());
}
  //默认json
  //这个方法把xml的converter使用的顺序放在了最后面
this.reorderXmlConvertersToEnd(converters);
return converters;
}

注:  
HttpMessageConverters 被spring 自动装配为bean(HttpMessageConvertersAutoConfiguration)
涉及spring 组件 HttpMessageConverters  -> WebMvcConfigurationSupport  
涉及较多自动装配的bean 和spring 底层组件,利用 打断点 + IDEA debug 模式 Drop Frame 功能 可以方便走通执行流程

参考:

用idea debug模式的drop frame功能, 辅助调试spring 框架底层组件代码

主要参考了 https://www.dabu.info/springmvc-content-negotiation-xml-troubleshoot.html

https://jishuin.proginn.com/p/763bfbd73865

https://blog.csdn.net/javaboyweng/article/details/122884234

排序规则 https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/MediaType.html#sortByQualityValue(java.util.List)

posted @   DeweyH  阅读(469)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示