SpringMVC使用了@ResponseBody报406错误的问题(1)

来源:互联网 发布:网络销售贵金属好做吗 编辑:程序博客网 时间:2024/04/30 02:09

    昨天在编写一个程序的时候,使用@ResponseBody,以此返回一个json格式的数据,后来发现前台一直报406错误,上网找了很久,有的是配置  

<mvc:annotation-driven><mvc:message-converters><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>
    解决的(需要导入fastjson相关包)

    有的是配置

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">        <property name="messageConverters">            <list>                <bean class="org.springframework.http.converter.StringHttpMessageConverter">                    <property name="supportedMediaTypes">                        <list>                            <value>text/html; charset=UTF-8</value>                            <value>application/json;charset=UTF-8</value>                        </list>                    </property>                </bean>                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">                    <property name="supportedMediaTypes">                        <list>                            <value>text/html; charset=UTF-8</value>                            <value>application/json;charset=UTF-8</value>                        </list>                    </property>                </bean>            </list>        </property>    </bean>
    解决的(需要导入jackon相关包)
    但是,我在这边这两种方法都无效,暂时不知道为什么,然后在网上找到个例子,下载下来之后,里面没有上面的两种配置,只是加了@ResponseBody注解就可以用了,看了一下jar包,发现他用的是3.1.2版本的,而我用的是3.2.5版本的,不知道是不是这个问题,于是debug一下,出现这个问题的原因终于被我找出来了,如下

    两个版本的AbstractMessageConverterMethodProcessor类都有一个方法:getAcceptableMediaTypes,这个方法获取可以接收资源类型,就是这个地方,两个版本的处理方式不一样,所以,导致两个版本的结果也不一样,我们看一下实现:

    3.2.5版本:

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;}
    3.1.2版本:
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();}}
    很明显,两个方法不一样,关键的的是第一句代码,3.1.2版本的是直接获取请求头中的Accept,请求头中的Accept为*/*(使用jquery的ajax请求的时候,默认是*/*),所以,json类型的可以匹配到,所以转换成功,而3.2.5版本的获取的方式不是获取请求头,一路跟踪进去,发现它关键的代码实现如下:

protected String getMediaTypeKey(NativeWebRequest webRequest) {HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);if (servletRequest == null) {logger.warn("An HttpServletRequest is required to determine the media type key");return null;}String path = urlPathHelper.getLookupPathForRequest(servletRequest);String filename = WebUtils.extractFullFilenameFromUrlPath(path);String extension = StringUtils.getFilenameExtension(filename);return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;}
    它是从请求的路径来返回可接收的类型,我的SpringMVC匹配的是*.html后缀,所以,它最后返回的是text/html类型,显然,无法匹配,所以最后会报错

    根据上面的原因,我代码修改如下,便成功获取到了暑假:

    1、将*.html后缀改成/,406错误不报了,也成功的获取到了数据

    2、换成3.1.2版本的包,html和/都可以获取到数据

    这是我遇到的问题和解决的方法,发出来分享一下,而网上说的那2种配置的解决方法,在我这里无法解决问题,暂时不知道是什么原因。



1 0
原创粉丝点击