引言:
前幾天同學使用SpringMVC,在前端頁面使用AJAX請求後端數據的時候報了406 Not Acceptable的問題,當時也去度娘找解決方法,無奈找了好久沒找到。所以寫下來,免得以後遇到這個問題,自己想不起來!
1、先來看看代碼吧(看了部分代碼,估計已經有人看出來大概是什麼錯了)
1.1、後臺主要代碼
@Controller
public class FooController {
/**
* 返回一串測試的json數據
*
* @return {"name":"LinHenk"}
*/
@RequestMapping(value = "foo/getJson", method = RequestMethod.GET)
@ResponseBody
public Map<String,String> getJson() {
Map<String,String> map = new HashMap<String, String>();
map.put("name","linhenk" );
return map;
}
//其他方法省略
}
1.2、前臺代碼主要代碼(點擊button,然後ajax向後臺請求數據)
<script type="text/javascript">
$(function(){
$("#btn").click(function(){
$.ajax({
//foo/getJson後端方法的請求路徑
url : "foo/getJson.html",
type : "get",
dataType : "json",
success : function(data){
alert(data.name);
}
});
})
})
</script>
1.3、web.xml中SpringMVC的DispatcherServlet的配置(這裏看出貓膩基本就不用看下面了)
<!-- 配置SpringMVC框架入口 -->
<servlet>
<servlet-name>springmvc-406</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/SpringMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-406</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
2、在瀏覽器進行對頁面訪問,並且點擊按鍵,使其向後臺系統請求數據
那麼來看看報的是什麼錯:
Request URL:http://localhost:8080/springmvc-406/foo/getJson.html
Request Method:GET
Status Code:406 Not Acceptable
Remote Address:[::1]:8080
3、度娘上找到的解決方法
大部分的答案都是,因爲程序中使用到了@ResponseBody該註解,該註解可以將對象轉成json格式,但是@ResponseBody這個註解需要依賴jackson的相關jar包。
ps:如果同樣遇到406問題的朋友,請先看看是否缺少jackson相關的jar包,如果是缺少相關jar可以使用如下方法解決:
3.1、maven工程(添加以下依賴既可解決,注意jackson的版本是否和您當前SpringMVC的版本衝突):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.2</version>
</dependency>
3.2、非maven工程,通過以下鏈接點擊下載jackson-2.4.2,進行下載,將下載好的jar包,加入到工程中
4、工程中已存在jackson的相關jar包
看看日誌文件:
2017-01-19 09:59:35,607 [http-bio-8080-exec-7] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] DispatcherServlet with name 'springmvc-406' processing GET request for [/springmvc-406/foo/getJson.html]
2017-01-19 09:59:35,607 [http-bio-8080-exec-7] [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /foo/getJson.html
2017-01-19 09:59:35,609 [http-bio-8080-exec-7] [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public java.util.Map<java.lang.String, java.lang.String> com.henk.springmvc.error406.controller.FooController.getJson()]
2017-01-19 09:59:35,610 [http-bio-8080-exec-7] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'fooController'
2017-01-19 09:59:35,613 [http-bio-8080-exec-7] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Last-Modified value for [/springmvc-406/foo/getJson.html] is: -1
2017-01-19 09:59:35,638 [http-bio-8080-exec-7] [org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver]-[DEBUG] Resolving exception from handler [public java.util.Map<java.lang.String, java.lang.String> com.henk.springmvc.error406.controller.FooController.getJson()]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
2017-01-19 09:59:35,640 [http-bio-8080-exec-7] [org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver]-[DEBUG] Resolving exception from handler [public java.util.Map<java.lang.String, java.lang.String> com.henk.springmvc.error406.controller.FooController.getJson()]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
2017-01-19 09:59:35,640 [http-bio-8080-exec-7] [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver]-[DEBUG] Resolving exception from handler [public java.util.Map<java.lang.String, java.lang.String> com.henk.springmvc.error406.controller.FooController.getJson()]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
2017-01-19 09:59:35,641 [http-bio-8080-exec-7] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Null ModelAndView returned to DispatcherServlet with name 'springmvc-406': assuming HandlerAdapter completed request handling
2017-01-19 09:59:35,641 [http-bio-8080-exec-7] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Successfully completed request
由以上日誌可以看出,請求已經執行,但是在springmvc在進行響應的時候,產生了406
5、解決方法
前面有一個很重要的xml代碼,就是配置SpringMVC的DispatcherServlet的代碼
<servlet-mapping>
<servlet-name>springmvc-406</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
就是這段配置的問題,url-pattern爲*.html,在SpringMVC中如果請求以html結尾,那麼就不會返回JSON數據,這是SpringMVC所規定的
怎麼解決?
我們將url-pattern配置爲*.html
,是想使用僞靜態,來提高網站的SEO,所以直接將url-pattern改成*.xxx
是不太合適的。不過我們可以提供多路路徑進入SpringMVC。
代碼如下:
<!-- 配置SpringMVC框架入口 -->
<servlet>
<servlet-name>springmvc-406</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/SpringMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 通過html結尾進入SpringMVC -->
<servlet-mapping>
<servlet-name>springmvc-406</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- 通過/service/* 進入SpringMVC-->
<servlet-mapping>
<servlet-name>springmvc-406</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
所以前端代碼可以修改爲以下形式即可解決406錯誤:
<script type="text/javascript">
$(function(){
$("#btn").click(function(){
$.ajax({
url : "service/foo/getJson",
type : "get",
dataType : "json",
success : function(data){
alert(data.name);
}
});
})
})
</script>
解決後的效果:
6、小結
以上就是整個的406報錯的解決過程,寫得可能不是很清晰,但是隻要注意以下幾點就可以避免文中的出現兩個SpringMVC的錯誤:
1. 導入Jackson所依賴的相關JAR
2.儘量避免向以html結尾的路徑請求JSON數據,如果實在不能避免,配置多路徑進入SpringMVC