添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议 》和 《 阿里云开发者社区知识产权保护指引 》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单 进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

后台代码:

[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" />

<!-- 定义视图解析器 -->

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

public Map<String, Object> findWxmpType() {

Long startTime = System. currentTimeMillis ();

Map<String,Object> maps = new HashMap<String, Object>();

try {

// 微信公众号搜索列表

maps .put( "msg" , "success" );

LOGGER .debug( " 响应结果: maps {} " , maps );

} catch (Exception e ) {

LoggerUtil. errorLog ( " 执行失败 " , startTime , System. currentTimeMillis (),

LOGGER , e );

maps .put( "msg" , " 加载数据异常,请稍后再试 " );

return maps ;

问题跟踪分析

通过 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">

<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,如需转载请自行联系原作者