Spring4 MVC json有关问题(406 Not Acceptable)
Spring4 MVC json问题(406 Not Acceptable)
最近使用spring4.0.5版本的Mvc,json请求时,客户端报错,406 Not Acceptable。
原因分析
在百度GOOGLE半天无果后,果断开始debug。
首先定位在org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor类中的下面代码处抛出了异常。
if (compatibleMediaTypes.isEmpty()) { throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes); }
由此看来是compatibleMediaTypes为空导致的,由于之前一直使用spring3.1没有出现够相关的问题,于是切换到3.1继续debug,发现3.1的requestedMediaTypes为[*/*], 而3.2的requestedMediaTypes却为[text/html]。到此几乎可以确定在3.1版本与4.0.5版本中获取acceptableMediaTypes的方式肯定是有所差异的。
定位到每个版本的getAcceptableMediaTypes方法上,继续查看。
spring 3.1
private List<MediaType> getAcceptableMediaTypes( HttpInputMessage inputMessage) { try { List<MediaType> result = inputMessage.getHeaders().getAccept(); return result.isEmpty() ? Collections.singletonList(MediaType.ALL) : result; } catch (IllegalArgumentException ex) { if (logger.isDebugEnabled()) { logger.debug("Could not parse Accept header: " + ex.getMessage()); } return Collections.emptyList(); } }
spring 4.0.5
进入到getAcceptableMediaTypes方法,发现通过resolveMediaTypes获取MediaType的。
private List<MediaType> getAcceptableMediaTypes(HttpServletRequest request) throws HttpMediaTypeNotAcceptableException { List<MediaType> mediaTypes = this.contentNegotiationManager.resolveMediaTypes(new ServletWebRequest(request)); return (mediaTypes.isEmpty() ? Collections.singletonList(MediaType.ALL) : mediaTypes); }
接着进入resolveMediaTypes方法
@Override public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException { for (ContentNegotiationStrategy strategy : this.contentNegotiationStrategies) { List<MediaType> mediaTypes = strategy.resolveMediaTypes(webRequest); if (mediaTypes.isEmpty() || mediaTypes.equals(MEDIA_TYPE_ALL)) { continue; } return mediaTypes; } return Collections.emptyList(); }
看来问题就是出在这里了。
解决办法
办法一
1、导入第三方的jackson包,jackson-mapper-asl-1.9.7.jar和jackson-core-asl-1.9.7.jar。
2、Spring配置文件添加:
<mvc:annotation-driven/> <!-- 避免IE执行AJAX时,返回JSON出现下载文件 --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 --> </list> </property> </bean>
办法二
1、导入第三方的fastjson包,fastjson-1.1.34.jar
2、Spring配置文件添加:
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <!-- 避免IE执行AJAX时,返回JSON出现下载文件 --> <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>