zoukankan      html  css  js  c++  java
  • 76. Spring Boot完美解决(406)Could not find acceptable representation原因及解决方法

    【原创文章】

           使用Spring Boot的Web项目,处理/login请求的控制器方法(该方法会返回JSON格式的数据)。此时如果访问localhost:8080/login.html,用户期望返回jsons数据,但框架却报错:

    There was an unexpected error (type=Not Acceptable, status=406).

    Could not find acceptable representation

    或者这样的异常信息:

    org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

        at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:235) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]

        at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:382) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]

    错误原因:

           Spring Boot的MVC默认配置中使用的 ViewResolver 为 ContentNegotiatingViewResolver,该视图解析器的功能是根据要请求的文档类型,来查找不同的视图以返回对应格式的文档。请求的文档类型要可以从请求头中的Accept中获取,也可以通过URI后缀名得到,如/login.html即为请求HTML格式的文档,这两种方式分别对应着两种不同的Strategy(策略),默认为根据URI后缀名。

    ContentNegotiatingViewResolver中有说明:

    The ContentNegotiatingViewResolver does not resolve views itself but rather delegates to other view resolvers, selecting the view that resembles the representation requested by the client. Two strategies exist for a client to request a representation from the server: 
    • Use a distinct URI for each resource, typically by using a different file extension in the URI. For example, the URIhttp://www.example.com/users/fred.pdf requests a PDF representation of the user fred, and http://www.example.com/users/fred.xmlrequests an XML representation. 
    • Use the same URI for the client to locate the resource, but set the Accept HTTP request header to list the media types that it understands. For example, an HTTP request for http:// www.example.com/users/fred with an Accept header set to application/pdf requests a PDF representation of the user fred, while http://www.example.com/users/fred with an Accept header set to text/xml requests an XML representation. This strategy is known as content negotiation.

          

            因此,当用户请求 /login.html 时,spring会查找/login对应的控制器,并得到其返回的文档类型为application/json, 然后判断它与后缀名.html文档类型是否匹配,如果不匹配,就报HttpMediaTypeNotAcceptableException了。

           其实它的初衷是好的,它是想实现访问/user.json时返回JSON数据,访问/user.html返回HTML, 访问/user.xml则返回XML的功能。但是在这里我们只用Spring Boot提供RESTful接口,因此该功能就无用武之地了。

    解决方案

           我们刚才在上面说了Spring 会通过URI后缀获取请求格式,当访问/login.html的时候,那么根据当前的URI获取到后缀.html,那么判断与.html文档类型是否匹配,匹配的话执行相应的解析器。那么我们就会想,我们能够关闭这种默认的后缀匹配规则呢,既然本文章说是完美解决答案就是肯定的。解决步骤就两步骤:

    (1)在启动类App.java类中继承:WebMvcConfigurerAdapter

    (2)覆盖方法:configureContentNegotiation

    具体代码如下:

    package com.kfit;

    import org.springframework.boot.SpringApplication;

    import org.springframework.boot.autoconfigure.SpringBootApplication;

    import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;

    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

    /**

     *

     * @author Angel --守护天使

     * @version v.0.1

     * @date 2016年7月29日下午7:06:11

     */

    @SpringBootApplication

    public class ApiCoreApp extends WebMvcConfigurerAdapter {

       

        /**

         (1)在启动类App.java类中继承:WebMvcConfigurerAdapter

        (2)覆盖方法:configureContentNegotiation

       

        favorPathExtension表示支持后缀匹配,

        属性ignoreAcceptHeader默认为fasle,表示accept-header匹配,defaultContentType开启默认匹配。

           例如:请求aaa.xx,若设置<entry key="xx" value="application/xml"/> 也能匹配以xml返回。

    根据以上条件进行一一匹配最终,得到相关并符合的策略初始化ContentNegotiationManager  

         */

        @Override

       public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

            configurer.favorPathExtension(false);

        }

        public static void main(String[] args) {

           SpringApplication.run(ApiCoreApp.class, args);

        }

    }

           这里说下核心代码:

    configurer.favorPathExtension(false);

       favorPathExtension表示支持后缀匹配,

       属性ignoreAcceptHeader默认为fasle,表示accept-header匹配,defaultContentType开启默认匹配。

          例如:请求aaa.xx,若设置<entry key="xx" value="application/xml"/> 也能匹配以xml返回。

    根据以上条件进行一一匹配最终,得到相关并符合的策略初始化ContentNegotiationManager

  • 相关阅读:
    php 对输入信息的过滤代码
    svn命令备忘
    php下载文件的代码示例
    html中meta的用法
    程序员技术练级攻略
    JavaScript输出对象的内部结构
    转载Web架构师成长之路
    php代码执行效率测试工具xhprof安装&使用
    [译]Pro ASP.NET MVC 3 Framework 3rd Edition (Chapter 20 JQuery) 5.Using jQuery Events 使用jQuery事件
    [译]Pro ASP.NET MVC 3 Framework 3rd Edition (Chapter 20 JQuery) 6.Using jQuery Visual Effects 使用jQuery特效
  • 原文地址:https://www.cnblogs.com/stupidMartian/p/9143591.html
Copyright © 2011-2022 走看看