前段时间在做一个前后端分离的项目,在做异步请求的路径映射时,习惯性的把每个请求的后缀写成.html,然后配置DispactherServlet拦截.html结尾的请求。
结果就报出406错误。
406:Not acceptable。Web 服务器检测发现它想反馈的数据不能为客户端所接受,它则反馈一个含有 406 错误代码的报头。表示请求资源的MIME类型与客户端Accpet头信息中指定的类型不一致,所以客户端不接受。
具体原因:SpringMVC在我们未配置请求响应方式(ContentType)的情况下,会自动根据请求URL后缀如“.html”,给出一个默认的响应MIME类型,如“text/html”,而异步请求想要接收的是“application/json”,所以会出现406错误。下面我们看一下SpringMVC自动映射的类型有哪些
public class MediaType extends MimeType implements Serializable {
private static final long serialVersionUID = 2069937152339670231L;
public static final MediaType ALL = valueOf("*/*");
public static final String ALL_VALUE = "*/*";
public static final MediaType APPLICATION_ATOM_XML = valueOf("application/atom+xml");
public static final String APPLICATION_ATOM_XML_VALUE = "application/atom+xml";
public static final MediaType APPLICATION_FORM_URLENCODED = valueOf("application/x-www-form-urlencoded");
public static final String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded";
public static final MediaType APPLICATION_JSON = valueOf("application/json");
public static final String APPLICATION_JSON_VALUE = "application/json";
public static final MediaType APPLICATION_JSON_UTF8 = valueOf("application/json;charset=UTF-8");
public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";
public static final MediaType APPLICATION_OCTET_STREAM = valueOf("application/octet-stream");
public static final String APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream";
public static final MediaType APPLICATION_PDF = valueOf("application/pdf");
public static final String APPLICATION_PDF_VALUE = "application/pdf";
public static final MediaType APPLICATION_RSS_XML = valueOf("application/rss+xml");
public static final String APPLICATION_RSS_XML_VALUE = "application/rss+xml";
public static final MediaType APPLICATION_XHTML_XML = valueOf("application/xhtml+xml");
public static final String APPLICATION_XHTML_XML_VALUE = "application/xhtml+xml";
public static final MediaType APPLICATION_XML = valueOf("application/xml");
public static final String APPLICATION_XML_VALUE = "application/xml";
public static final MediaType IMAGE_GIF = valueOf("image/gif");
public static final String IMAGE_GIF_VALUE = "image/gif";
public static final MediaType IMAGE_JPEG = valueOf("image/jpeg");
public static final String IMAGE_JPEG_VALUE = "image/jpeg";
public static final MediaType IMAGE_PNG = valueOf("image/png");
public static final String IMAGE_PNG_VALUE = "image/png";
public static final MediaType MULTIPART_FORM_DATA = valueOf("multipart/form-data");
public static final String MULTIPART_FORM_DATA_VALUE = "multipart/form-data";
public static final MediaType TEXT_EVENT_STREAM = valueOf("text/event-stream");
public static final String TEXT_EVENT_STREAM_VALUE = "text/event-stream";
public static final MediaType TEXT_HTML = valueOf("text/html");
public static final String TEXT_HTML_VALUE = "text/html";
public static final MediaType TEXT_MARKDOWN = valueOf("text/markdown");
public static final String TEXT_MARKDOWN_VALUE = "text/markdown";
public static final MediaType TEXT_PLAIN = valueOf("text/plain");
public static final String TEXT_PLAIN_VALUE = "text/plain";
public static final MediaType TEXT_XML = valueOf("text/xml");
public static final String TEXT_XML_VALUE = "text/xml";
可以看到html默认映射contentType为“text/html”。
解决方案有两种
1、把请求后缀改为.json或者其他不在映射表中出现的,就不会有这个问题了。
2、在SpringMVC的bean容器中添加一个ContentNegotiationManagerFactoryBean,该Bean是内容协商管理工厂,用来配置多视图请求格式。在该工厂中添加一个属性。
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes">
<map>
<entry key="html" value="application/json;charset=UTF-8"/>
</map>
</property>
</bean>