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
【Spring Boot 系列博客】
61. mybatic insert异常:BindingException: Parameter 'name' not found【从零开始学Spring B】
60. Spring Boot写后感【从零开始学Spring Boot】
59. Spring Boot Validator校验【从零开始学Spring Boot】
58. Spring Boot国际化(i18n)【从零开始学Spring Boot】
57. Spring 自定义properties升级篇【从零开始学Spring Boot】
56. spring boot中使用@Async实现异步调用【从零开始学Spring Boot】
55. spring boot 服务配置和部署【从零开始学Spring Boot】
54. spring boot日志升级篇—logback【从零开始学Spring Boot】
52. spring boot日志升级篇—log4j多环境不同日志级别的控制【从零开始学Spring Boot】
51. spring boot属性文件之多环境配置【从零开始学Spring Boot】
50. Spring Boot日志升级篇—log4j【从零开始学Spring Boot】
49. spring boot日志升级篇—理论【从零开始学Spring Boot】
48. spring boot单元测试restfull API【从零开始学Spring Boot】
47. Spring Boot发送邮件【从零开始学Spring Boot】
46. Spring Boot中使用AOP统一处理Web请求日志
45. Spring Boot MyBatis连接Mysql数据库【从零开始学Spring Boot】
44. Spring Boot日志记录SLF4J【从零开始学Spring Boot】
43. Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
42. Spring Boot多数据源【从零开始学Spring Boot】
41. Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】
40. springboot + devtools(热部署)【从零开始学Spring Boot】
39.4 Spring Boot Shiro权限管理【从零开始学Spring Boot】
39.3 Spring Boot Shiro权限管理【从零开始学Spring Boot】
39.2. Spring Boot Shiro权限管理【从零开始学Spring Boot】
39.1 Spring Boot Shiro权限管理【从零开始学Spring Boot】
38 Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】
37 Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】
36 Spring Boot Cache理论篇【从零开始学Spring Boot】
35 Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】
34Spring Boot的启动器Starter详解【从零开始学Spring Boot】
33 Spring Boot 监控和管理生产环境【从零开始学Spring Boot】
76. Spring Boot完美解决(406)Could not find acceptable representation原因及解决方法的更多相关文章
- 78. Spring Boot完美使用FastJson解析JSON数据【从零开始学Spring Boot】
[原创文章,转载请注明出处] 个人使用比较习惯的json框架是fastjson,所以spring boot默认的json使用起来就很陌生了,所以很自然我就想我能不能使用fastjson进行json解析 ...
- spring cloud spring boot JPA 克隆对象修改属性后 无法正常的执行save方法进行保存或者更新
2019-12-1220:34:58 spring cloud spring boot JPA 克隆对象修改属性后 无法正常的执行save方法进行保存或者更新 未解决
- centos7.5 解决缺少libstdc++.so.6库的原因及解决办法
centos7. 解决缺少libstdc++.so.6库的原因及解决办法 执行node -v报错如下: [root@bogon ~]# node -v node: error : cannot ope ...
- spring boot项目自定义数据源,mybatisplus分页、逻辑删除无效解决方法
Spring Boot项目中数据源的配置可以通过两种方式实现: 1.application.yml或者application.properties配置 2.注入DataSource及SqlSessio ...
- Eclipse 配置spring boot pom.xml第1行报错的两种解决办法
现象 通过spring boot项目导入eclipse后,pom.xml文件的第一行总是报错.这里使用的spring版本是2.1.5,2.1.4以前的版本等其他版本的spring没有这个问题. 解决办 ...
- Spring Boot 整合Mybatis非starter时,mapper一直无法注入解决
本来呢,直接使用mybatis-spring-boot-starter还是挺好的,但是我们系统比较复杂,有多个数据源,其中一个平台自己的数据源,另外一些是动态配置出来的,两者完全没有关系.所以直接使用 ...
- spring boot 2.0 报错:“jdbcUrl is required with driverClassName.” 解决办法!
springboot 升级到2.0之后发现配置多数据源的时候报错: "jdbcUrl is required with driverClassName."或者Cause: java ...
- 在使用 Spring Boot 和 MyBatis 动态切换数据源时遇到的问题以及解决方法
相关项目地址:https://github.com/helloworlde/SpringBoot-DynamicDataSource 1. org.apache.ibatis.binding.Bind ...
- Spring Boot 调用 MongoRepository时报org.springframework.beans.factory.NoSuchBeanDefinitionException错误的解决办法
这个问题整整折腾了我两天,现在记录下来,希望可以帮助和我一样,遇到相同问题的小伙伴. 项目是分层的(Intellij IDEA中的模块Module),有API(Core)层,Service&D ...
随机推荐
- System.Web.Mvc 和 using System.Net.Http 的 Filter
在尝试给webapi增加 ExceptionFilter时,出现了错误,经查询区别如下: System.Web.Mvc.Filters 是给mvc用的 System.Web.Http.Filters ...
- GDI双缓冲绘图
一.简介 在进行复杂图形绘制时,若直接在屏幕DC上进行绘制,则会出现明显的闪烁.闪烁产生的原因是当绘制的图形较为 复杂时,图形绘制过程中就被刷新到屏幕上,导致结果断断续续地显示出来.双缓冲绘图的原理是 ...
- Hibernate的一级缓存:快照区
参考来源:http://blog.sina.com.cn/s/blog_981ee5d80102w85f.html
- vue的开发技巧
1.监听组件的生命周期 比如有父组件 Parent和子组件 Child,如果父组件监听到子组件挂载 mounted就做一些逻辑处理,常规的写法可能如下: // Parent.vue <Child ...
- eclipse XML TAB键默认为四个空格
- json2.js 源码解读
这一部分是对Date String Number Boolean扩展toString方法,Date的toString是返回UTC格式的字符串,而后面几个是返回原始值. function f(n) {/ ...
- 作用域链、this细说
一.作用域链 作用域:浏览器给js的一个生存环境(栈内存) 作用域链:js中的关键字var和function 都可以提前声明和定义,提前声明和定义的放在我们的内存地址(堆内存)中.然后js从上到下逐行 ...
- ES之基本数据类型之间的显示转换和隐式转换
typeof(数据)/ typeof 数据 判断数据的数据类型,typeof返回的都是字符串 输出结果类型有:number.string.boolean. undefined.object.funct ...
- 移动端超级好用的reset.css(只做参考哦具体以你们实际项目需求为准)
html { color: #333; /*规定主色调,依据业务场景(非必须)*/ background: #F6F6F6; /*规定主背景,依据业务场景(非必须)*/ overflow-y: aut ...
- Elasticsearch搜索含有数字标签的处理
{"tag_id":“12345”} 在search的时候是完全匹配,因为Elasticsearch在处理这个的过程中把“123456”字符当成一个整体的数据,因此折腾了好久就是找 ...