Springmvc通过@ResponseBody标签返回JSON数据的方法都报406 (Not Acceptable)错

引言: 
前几天同学使用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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2、在浏览器进行对页面访问,并且点击按键,使其向后台系统请求数据

那么来看看报的是什么错: 
这里写图片描述

Request URL:http://localhost:8080/springmvc-406/foo/getJson.html
Request Method:GET
Status Code:406 Not Acceptable
Remote Address:[::1]:8080
  • 1
  • 2
  • 3
  • 4

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>
  • 1
  • 2
  • 3
  • 4
  • 5

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

由以上日志可以看出,请求已经执行,但是在springmvc在进行响应的时候,产生了406

5、解决方法

前面有一个很重要的xml代码,就是配置SpringMVC的DispatcherServlet的代码

<servlet-mapping>
        <servlet-name>springmvc-406</servlet-name>
        <url-pattern>*.html</url-pattern>
</servlet-mapping>
  • 1
  • 2
  • 3
  • 4

就是这段配置的问题,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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

所以前端代码可以修改为以下形式即可解决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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

解决后的效果:

这里写图片描述

6、小结

以上就是整个的406报错的解决过程,写得可能不是很清晰,但是只要注意以下几点就可以避免文中的出现两个SpringMVC的错误: 
1. 导入Jackson所依赖的相关JAR 
2.尽量避免向以html结尾的路径请求JSON数据,如果实在不能避免,配置多路径进入SpringMVC


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值