Spring JSON request getting 406 (not Acceptable)

2019-01-01 09:20发布

this is my javascript:

    function getWeather() {
        $.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) {
            alert('Success');                               
        });
    }

this is my controller:

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
@ResponseBody
public Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

spring-servlet.xml

<context:annotation-config />
<tx:annotation-driven />

Getting this error:

GET http://localhost:8080/web/getTemperature/2 406 (Not Acceptable)

Headers:

Response Headers

Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  1070
Date    Sun, 18 Sep 2011 17:00:35 GMT

Request Headers

Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept  application/json, text/javascript, */*; q=0.01
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/web/weather
Cookie  JSESSIONID=7D27FAC18050ED84B58DAFB0A51CB7E4

Interesting note:

I get 406 error, but the hibernate query works meanwhile. This is what tomcat log says, everytime when I change selection in dropbox:

 select weather0_.ID as ID0_0_, weather0_.CITY_ID as CITY2_0_0_, weather0_.DATE as DATE0_0_, weather0_.TEMP as TEMP0_0_ from WEATHER weather0_ where weather0_.ID=?

What could the problem be? There were two similar questions in SO before, I tried all the accepted hints there, but they did not work I guess...

Any suggestions? Feel free to ask questions...

21条回答
深知你不懂我心
2楼-- · 2019-01-01 09:29

406 Not Acceptable

The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.

So, your request accept header is application/json and your controller is not able to return that. This happens when the correct HTTPMessageConverter can not be found to satisfy the @ResponseBody annotated return value. HTTPMessageConverter are automatically registered when you use the <mvc:annotation-driven>, given certain 3-d party libraries in the classpath.

Either you don't have the correct Jackson library in your classpath, or you haven't used the <mvc:annotation-driven> directive.

I successfully replicated your scenario and it worked fine using these two libraries and no headers="Accept=*/*" directive.

  • jackson-core-asl-1.7.4.jar
  • jackson-mapper-asl-1.7.4.jar
查看更多
梦醉为红颜
3楼-- · 2019-01-01 09:29

There is another case where this status will be returned: if the Jackson mapper cannot figure out how to serialize your bean. For example, if you have two accessor methods for the same boolean property, isFoo() and getFoo().

What's happening is that Spring's MappingJackson2HttpMessageConverter calls Jackson's StdSerializerProvider to see if it can convert your object. At the bottom of the call chain, StdSerializerProvider._createAndCacheUntypedSerializer throws a JsonMappingException with an informative message. However, this exception is swallowed by StdSerializerProvider._createAndCacheUntypedSerializer, which tells Spring that it can't convert the object. Having run out of converters, Spring reports that it's not being given an Accept header that it can use, which of course is bogus when you're giving it */*.

There is a bug for this behavior, but it was closed as "cannot reproduce": the method that's being called doesn't declare that it can throw, so swallowing exceptions is apparently an appropriate solution (yes, that was sarcasm). Unfortunately, Jackson doesn't have any logging ... and there are a lot of comments in the codebase wishing it did, so I suspect this isn't the only hidden gotcha.

查看更多
只靠听说
4楼-- · 2019-01-01 09:29

This is update answer for springVersion=5.0.3.RELEASE.

Those above answers will be only worked older springVersion < 4.1 version. for latest spring you have to add following dependencies in gradle file:

compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: fasterxmljackson
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: fasterxmljackson

fasterxmljackson=2.9.4

I hope this will be helpful for who using latest spring version.

查看更多
伤终究还是伤i
5楼-- · 2019-01-01 09:31

Can you remove the headers element in @RequestMapping and try..

Like


@RequestMapping(value="/getTemperature/{id}", method = RequestMethod.GET)

I guess spring does an 'contains check' rather than exact match for accept headers. But still, worth a try to remove the headers element and check.

查看更多
有味是清欢
6楼-- · 2019-01-01 09:32

check this thread. spring mvc restcontroller return json string p/s: you should add jack son mapping config to your WebMvcConfig class

@Override protected void configureMessageConverters( List<HttpMessageConverter<?>> converters) { // put the jackson converter to the front of the list so that application/json content-type strings will be treated as JSON converters.add(new MappingJackson2HttpMessageConverter()); // and probably needs a string converter too for text/plain content-type strings to be properly handled converters.add(new StringHttpMessageConverter()); }

查看更多
忆尘夕之涩
7楼-- · 2019-01-01 09:36

In the controller, shouldn't the response body annotation be on the return type and not the method, like so :

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
public @ResponseBody Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

I'd also use the raw jquery.ajax function, and make sure contentType and dataType are being set correctly.

On a different note, I find the spring handling of json rather problematic. It was easier when I did it all myself using strings, and GSON.

查看更多
登录 后发表回答