惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
Apple Machine Learning Research
Apple Machine Learning Research
量子位
D
DataBreaches.Net
云风的 BLOG
云风的 BLOG
博客园 - 聂微东
博客园_首页
D
Docker
博客园 - 叶小钗
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
F
Fortinet All Blogs
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
爱范儿
爱范儿
腾讯CDC
罗磊的独立博客
雷峰网
雷峰网
博客园 - Franky

祈雨的笔记

安全多方计算MPC spark原理解析 kueue执行源码分析 spark on k8s执行源码分析 spark-operator源码解析 系统压测遇到的缓存击穿问题 我的世界PC与安卓联机 蚂蚁金服流量投放平台的AIG改造 G1大对象致Old区占用率高 日志打印导致接口响应率下跌分析 Groovy加载类导致OOM分析 ERROR日志打印导致CPU满载 记OceanBase死锁超时 应用发版期间服务响应超时 Ark Serverless初探 系统优化复盘一二三 The user specified as a definer does not exist Kong网关初探 API网关选型调研 CPU火焰图常用工具 配置中心选型调研 root操作Nginx导致用户组错误 基于Proxifier使用代理 FastJSON字段智能匹配踩坑 Nacos初探 记一次Nginx服务器CPU满荷载故障 基于券系统分库分表的思考 limit不参与SQL成本计算致索引失效 Linux常用性能监控命令 golang低版本http2偶现400
SpringMVC @ResponseBody注解 json转换 返回406
祈雨的笔记 · 2017-10-02 · via 祈雨的笔记

1、描述

SpringMVC通过@RequestMapping注解,自动将对象转换为接送返回。浏览器请求后却返回406错误码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Controller
public class IndexAction {
@RequestMapping("/userList")
public @ResponseBody List<TXUser> userList(String updated_at){
System.out.println(updated_at);
TXUser user1=new TXUser();
user1.setAccount("a1");
user1.setCode("11");
user1.setCreated_at(new Date());
user1.setName("user1");
TXUser user2=new TXUser();
user2.setAccount("a2");
user2.setCode("22");
user2.setCreated_at(new Date());
user2.setName("user2");

List<TXUser> userslist=new ArrayList<TXUser>();
userslist.add(user1);
userslist.add(user2);
return userslist;
}

@RequestMapping("/index")
public String index(){
return "index";
}
}

2、原因

网上找过相关解决方法,但都是修改SpringMVC配置文件添加Converter。我对应修改后均无效。通过debug,发现返回406的原因是因为org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor中的writeWithMessageConverters方法出现异常。

1
2
3
4
5
6
7
8
9
10
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(servletRequest);
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));
}
}
}

以上代码中,各个变量的值最后分别为
变量|值
—|—
requestedMediaTypes|[text/html]
producibleMediaTypes|[application/json;charset=UTF-8,application/x-www-form-urlencoded;charset=UTF-8,application/json;charset=UTF-8,application/*+json;charset=UTF-8]
compatibleMediaTypes|[]

其中requestedMediaTypes为浏览器向SpringMVC的请求头,由于不匹配SpringMVC对应的请求头,最后返回406。

3、解决办法

找到对应原因,通过网络查找资料后,发现修改web.xml文件
原:

1
2
3
4
5
6
7
8
9
10
11
12
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

修改后:

1
2
3
4
5
6
7
8
9
10
11
12
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

修改xml后,浏览器再次请求后,正常返回json,不会返回406错误码了。
此时再次debug,三个变量的值分别为
变量|值
–|—
requestedMediaTypes|[text/html,application/xhtml+xml, image/webp,application/xml;q=0.9,* /;q=0.8]
producibleMediaTypes|[application/json;charset=UTF-8,application/x-www-form-urlencoded;charset=UTF-8,application/json;charset=UTF-8, application/
+json;charset=UTF-8]
compatibleMediaTypes|[application/json;charset=UTF-8;q=0.8,application/x-www-form-urlencoded;charset=UTF-8;q=0.8,application/*+json;charset=UTF-8;q=0.8]