SpringMVC使用了@ResponseBody報406錯誤的問題(1)_SpringMVC

來源:互聯網
上載者:User

    昨天在編寫一個程式的時候,使用@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種配置的解決方案,在我這裡無法解決問題,暫時不知道是什麼原因。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.