spring 4 异常HttpMediaTypeNotAcceptableException解决方案
异常问题
jsp页面ajax请求错误:406Not Acceptable
后台代码:
[2017:05:1709:51:22]:Resolving exception from handler [publicjava.util.Map<java.lang.String, java.lang.Object> com.demo.controller.DemoController.findWxmpType()]:org.springframework.web.HttpMediaTypeNotAcceptableException: Could not findacceptable representation
项目环境
项目环境:spingMVC 4.1.3 + spring + mybatis + jsp + jquery
传输数据格式:json
debug调试
【想直接看解决方案的,请直接到文章末尾处】
项目代码及相关配置
spring MVC部分配置:
<!-- 注解驱动 -->
<mvc:annotation-driven>
<!-- 如果自定义message-converters,默认的message-converters将失效 -->
<mvc:message-converters>
<!-- 定义文本转化器 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg index="0"value="UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 定义Controller的扫描包 -->
<context:component-scan base-package="com.demo.controller"/>
<!-- 定义视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"value="/WEB-INF/pages/" />
<property name="suffix"value=".jsp" />
</bean>
<!-- 处理静态资源被“/”所拦截的问题 -->
<mvc:default-servlet-handler />
web.xml部分配置:
<!-- 加载spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext*.xml</param-value>
</context-param>
<!--Spring的ApplicationContext 载入:Spring的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 加载SpringMVC的配置文件 -->
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/demo-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置访问映射的视图路径和后缀 -->
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!—所有请求 -->
<!--<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>-->
jsp页面:
$.post(path+"/wxmp/findWxmpType.html",function(data){
alert(data);
console.info("msg:"+data.msg);
if(data.msg=="success"){
alert(data.msg);
}})
Controller代码:
@RequestMapping(value = "/findWxmpType", method =RequestMethod.POST)
@ResponseBody
publicMap<String, Object> findWxmpType() {
Long startTime = System.currentTimeMillis();
Map<String,Object> maps= newHashMap<String, Object>();
try {
// 微信公众号搜索列表
maps.put("msg", "success");
LOGGER.debug("响应结果:maps【{}】", maps);
} catch (Exception e) {
LoggerUtil.errorLog("执行失败", startTime, System.currentTimeMillis(),
LOGGER, e);
maps.put("msg", "加载数据异常,请稍后再试");
}
returnmaps;
}
问题跟踪分析
通过debug跟踪,controller返回map集合数据是没有问题的。
问题点出在:springMVC在对返回数据进行转换处理的过程中!
网上百度了一下方法:
1,在controller返回的对象中必须包含getter/setter方法;(这个并不是问题原因)
2, 在controller的@RequestMapping(value= "/findWxmpType", method = RequestMethod.POST,produces="application/json")
加上红色字体部分。并没有解决问题,produces这个属性,大家可以百度下其具体作用是什么。简单来说:就是用于匹配页面的请求头Accept信息是否和响应头Accept信息(produces设置)一致。
3,配置jackson转换器,指定返回数据类型为text/html;
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<!--解决 HttpMediaTypeNotAcceptableException: Could not findacceptable
representation -->
<propertyname="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<!--<value>application/json;charset=UTF-8</value> -->
</list>
</property>
</bean>
这个解决方案,配置后运行效果如下:
数据是可以进行传输了,但已经不是json格式,jsp无法直接取到msg数据。
so,并没有解决问题!!!删除配置!
问题本质
springMVC在处理返回数据的时候是通过转换器HttpMessageConverter进行处理的。
org.springframework.web.HttpMediaTypeNotAcceptableException:Could not find acceptable representation
这个错误是:不能找到能接受的HttpMediaType协议。也就是说jsp页面的请求头Accept信息和controller返回的响应头accept头信息不一致。
前端jsp的Accept头信息:匹配所有。
更改配置
指定MediaTypes为json:
进入HttpMessageConverter转换器源码中:
插入一个小话题,eclipse跟踪异常源码方法:
点击蓝色部分:弹框:
点击OK。
源码跟踪
重新访问页面,进入debug断点:
跟踪A:
@Override
public List<MediaType>resolveMediaTypes(NativeWebRequest webRequest) throwsHttpMediaTypeNotAcceptableException {
for (ContentNegotiationStrategystrategy : this.contentNegotiationStrategies) {
List<MediaType>mediaTypes = strategy.resolveMediaTypes(webRequest);
if (mediaTypes.isEmpty() ||mediaTypes.equals(MEDIA_TYPE_ALL)) {
continue;
}
return mediaTypes;
}
return Collections.emptyList();
}
跟踪B:resolveMediaTypes(webRequest);
@Override
public List<MediaType>resolveMediaTypes(NativeWebRequest webRequest) throwsHttpMediaTypeNotAcceptableException {
String key =getMediaTypeKey(webRequest);
if (StringUtils.hasText(key)) {
MediaType mediaType =lookupMediaType(key);
if (mediaType != null) {
handleMatch(key,mediaType);
returnCollections.singletonList(mediaType);
}
mediaType =handleNoMatch(webRequest, key);
if (mediaType != null) {
addMapping(key,mediaType);
returnCollections.singletonList(mediaType);
}
}
return Collections.emptyList();
}
跟踪C:getMediaTypeKey(webRequest);从当前请求request当中获取到MediaType
@Override
protected String getMediaTypeKey(NativeWebRequestwebRequest) {
//获取request对象
HttpServletRequest servletRequest= webRequest.getNativeRequest(HttpServletRequest.class);
if (servletRequest == null) {
logger.warn("AnHttpServletRequest is required to determine the media type key");
return null;
}
//获取当前请求路径:/wxmp/searchWxmps.html
String path =urlPathHelper.getLookupPathForRequest(servletRequest);
//获取searchWxmps.html
String filename =WebUtils.extractFullFilenameFromUrlPath(path);
//获取请求后缀:html
String extension =StringUtils.getFilenameExtension(filename);
return(StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) :null;
}
回到:跟踪B:
下一步:
然后返回MediaType。
回到:跟踪A:
下一步:直到ProducesRequestConverter:
下一步:
@Override
protected booleanmatchMediaType(HttpServletRequest request) throwsHttpMediaTypeNotAcceptableException {
//acceptedMediaTypes=text/html 在经过springMVC解析之后的,页面想要的数据头信息
List<MediaType> acceptedMediaTypes =getAcceptedMediaTypes(request);
for (MediaTypeacceptedMediaType : acceptedMediaTypes) {
// getMediaType()=application/json我们配置的<value>application/json;charset=UTF8</value>
if(getMediaType().isCompatibleWith(acceptedMediaType)) {
return true;
}
}
return false;
}
结果就是:
结论
在从jsp页面发送ajax请求的时候,代码是:
$.post(path+"/wxmp/findWxmpType.html",function(data){}
请求路径为:http://m.demo.com/wxmp/findWxmpType.html这个后缀“.html”就是问题的根源。
该方法实际上只是为了请求数据,完全可以不带“.html”,但是在web.xml里面,进行的伪静态访问配置<servlet-mapping>
因为该配置,所有的访问,必须加上后缀“.html”才能进入后台。
带上这个配置之后,springMVC在解析前台请求头信息Accept的时候,原本是:*/* ,却解析成了:text/html
这样的话,我们在controller中加上@ResponseBody对返回数据进行json转换,设置响应头Accept=application/json之后,匹配matchProduces异常。
解决办法
1,在web.xml中添加这段配置:
<!—所有请求可进入 -->
<servlet-mapping>
<servlet-name>wupao-mwss</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
也就是放开 前文web.xml中最后的注释部分即可。
2,jsp页面请求更改为:$.post(path+"/wxmp/findWxmpType",function(data){}
去掉”.html”即可解决问题!!!
本文转自 wyait 51CTO博客,原文链接:http://blog.51cto.com/wyait/1926619,如需转载请自行联系原作者
spring 4 异常HttpMediaTypeNotAcceptableException解决方案相关推荐
- MySql数据库记录相差14小时排错,使用Java访问Mysql数据库时出现时区异常的解决方案
最近遇到1个大坑,A系统迁移到B系统,2边系统 同1个字段 createTime 看到的不一致. 表象: A系统: 2019-6-10 17:34 B系统: 2019-6-11 .... 再次尝试: ...
- Spring MVC异常统一处理(异常信息的国际化,日志记录)
JAVA EE项目中,不管是对底层的数据操作,还是业务层的处理过程,还是控制层的处理,都不可避免的会遇到各种可预知的(业务异常主动抛出).不可预知的异常需要处理.一般dao层.service层的异常都 ...
- Spring Cloud Alibaba一站式解决方案
一.Spring Cloud Alibaba一站式解决方案 在springCloud的基础上延伸出来的微服务技术栈 为什么学习spring cloud alibaba? spring cloud多项组 ...
- spring全局异常抓取validation校验信息
spring全局异常抓取validation校验信息 参考文章: (1)spring全局异常抓取validation校验信息 (2)https://www.cnblogs.com/jianxiaopo ...
- celery 运行时 (from . import async, base)SyntaxError: invalid syntax 异常的解决方案
celery 运行时 (from . import async, base)SyntaxError: invalid syntax 异常的解决方案 参考文章: (1)celery 运行时 (from ...
- spring mvc异常统一处理(ControllerAdvice注解)
spring mvc异常统一处理(ControllerAdvice注解) 参考文章: (1)spring mvc异常统一处理(ControllerAdvice注解) (2)https://www.cn ...
- MYSQL连接一段时间不操作后出现异常的解决方案
MYSQL连接一段时间不操作后出现异常的解决方案 参考文章: (1)MYSQL连接一段时间不操作后出现异常的解决方案 (2)https://www.cnblogs.com/bokejiayuan/p/ ...
- spring boot 异常(exception)处理
spring boot 异常(exception)处理 参考文章: (1)spring boot 异常(exception)处理 (2)https://www.cnblogs.com/jinbuqi/ ...
- Spring事务异常回滚,try catch 捕获异常不回滚
Spring事务异常回滚,try catch 捕获异常不回滚 参考文章: (1)Spring事务异常回滚,try catch 捕获异常不回滚 (2)https://www.cnblogs.com/GH ...
最新文章
- SAP HUM 嵌套HU初探 II
- python3 bytes与hex字符串互转
- math.h头文件中声明了常用的一些数学运算
- char* 和 char * 思考
- SpringBoot自定义参数
- VS2015 无法启动 IIS Express Web 服务器 解决方案
- python3 将列表中元素转化为字典_软件测试学Python(七):Python中的变量和标准数据类型...
- 数据结构与算法python—2.顺序表(数组)以及python实现
- 利用openssl创建私有CA的步骤和过程
- Spring实现Controller中方法参数校验
- IT软件开发人员必去的10个社区
- 【信息学奥赛一本通 提高组】第三章 深搜的剪枝技巧
- python爬虫-scrapy基于selenium进行网页截图
- 阿里云SMS短信服务的使用
- 机器学习必备知识点 之 先验概率和后验概率
- php printer_open 用法_php – 调用未定义的函数printer_open()
- SQL CHECK 约束
- MySql安装配置(msi版)
- 读:Multi-scale pulmonary nodule classification with deep feature fusion via residual network
- addEvent和removeEvent优化写法
热门文章
- 计算机任务类别 搜索服务,服务删除后仍要求启动 计划任务里找不到 该怎么办...
- android9 system_server 访问sd卡_Leez学院丨手把手教你栗子板Android9固件编译
- 计算机考研评分标准,考研的评分标准.doc
- 不用计算机怎么连接无线,不用电脑可以装wifi吗 不通过电脑装wifi方法【图文】...
- 亚太杯数学建模竞赛优秀论文_【优秀论文】2019数维杯国际大学生数学建模竞赛C题优秀论文...
- ajax获取json里的list,ajax获取json数据然后将其装载到jqgrid实现
- bootstrap思想总结_bootstrap学习心得总结-css样式设计分享
- 计算机网络四级题库word,计算机四级考试题库2016
- setState如何知道该做什么?
- php+彩票中奖判断,彩票算法 – PHP – 数学似乎不错,但功能是否有效?