[java] 406을받는 Spring JSON 요청 (허용되지 않음)
이것은 내 자바 스크립트입니다.
function getWeather() {
$.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) {
alert('Success');
});
}
이것은 내 컨트롤러입니다.
@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 />
이 오류가 발생합니다.
GET http://localhost:8080/web/getTemperature/2 406 (Not Acceptable)
헤더 :
응답 헤더
Server Apache-Coyote/1.1
Content-Type text/html;charset=utf-8
Content-Length 1070
Date Sun, 18 Sep 2011 17:00:35 GMT
요청 헤더
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…
답변
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
답변
I had same issue, with Latest Spring 4.1.1 onwards you need to add following jars to pom.xml.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.1</version>
</dependency>
also make sure you have following jar:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
406 Spring MVC Json, not acceptable according to the request “accept” headers
답변
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.
답변
I had the same problem, my controller method executes but response is Error 406.
I debug AbstractMessageConverterMethodProcessor#writeWithMessageConverters
and found that method ContentNegotiationManager#resolveMediaTypes
always returns text/html
which is not supported by MappingJacksonHttpMessageConverter
. The problem is that the org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy
works earlier than org.springframework.web.accept.HeaderContentNegotiationStrategy
, and extension of my request /get-clients.html
is the cause of my problem with Error 406. I just changed request url to /get-clients
.
답변
Make sure that following 2 jar
‘s are present in class path.
If any one or both are missing then this error will come.
jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar
답변
Finally found answer from here:
Mapping restful ajax requests to spring
I quote:
@RequestBody/@ResponseBody annotations don’t use normal view resolvers, they use their own HttpMessageConverters. In order to use these annotations, you should configure these converters in AnnotationMethodHandlerAdapter, as described in the reference (you probably need MappingJacksonHttpMessageConverter).
답변
Check <mvc:annotation-driven />
in dispatcherservlet.xml , if not add it.
And add
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
these dependencies in your pom.xml