Spring-MVC 406 不可接受而不是 JSON 响应
我尝试使用 Spring 3.0.6 返回 JSON 响应,但收到 406 响应“不可接受”,其描述为: “此请求所标识的资源只能生成具有特征的响应 根据请求“接受”标头 () 不可接受。”
我知道 以前曾问过一个非常相似的问题,但我无法让它适用于我的项目,尽管有很多 测试,我不明白我做错了什么。
在我的 Maven pom.xml 中,我有以下内容:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.8.5</version>
<scope>compile</scope>
</dependency>
在 web.xml 中,我引用 webmvc-config.xml,并且日志确认已加载。
<servlet>
<servlet-name>mainServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
在 webmvc-config.xml 中,我有以下内容:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:annotation-driven />
我的控制器是:
@Controller
public class ClassifiedController {
@RequestMapping(value = "/classified/{idClassified}", headers = "Accept=*/*",
method = RequestMethod.GET)
@ResponseBody
public final Classified getClassified(@PathVariable final int idClassified) {
...
我尝试使用或不使用 headers 参数,得到相同的结果。如果我调用 URL 直接使用 Firefox,请求标头包含以下内容(使用 firebug 检查):
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
如果我使用以下 JQuery:
$.ajax({
url: '/classified/38001',
type: 'GET',
dataType: 'json'
});
发送以下标头:
Accept: application/json, text/javascript, */*; q=0.01
在这两种情况下,结果都是 406 错误。我不知道我还应该检查什么 它起作用了。
更新:我决定通过 Spring 进行调试,发现 Jackson 被正确调用,并且在 org.codehaus.jackson.map.ser.StdSerializerProvider 中,方法 _findExplicitUntypedSerializer 包含以下代码:
try {
return _createAndCacheUntypedSerializer(runtimeType, property);
} catch (Exception e) {
return null;
}
这是不幸的,因为隐藏了问题的根源。通过调试器,我发现该异常包含一条非常具有描述性的错误消息:
Conflicting getter definitions for property "reminded":
ClassifiedImpl#isReminded(0 params) vs
ClassifiedImpl#getReminded(0 params)
现在我看到该错误消息是一个愚蠢的错误并且很容易修复,但如果没有它,它就不那么明显了。事实上,解决问题后,序列化就可以工作了。
I'm trying to return a JSON response with Spring 3.0.6, but I get a 406 response "Not Acceptable", with the description:
"The resource identified by this request is only capable of generating responses with characteristics
not acceptable according to the request "accept" headers ()."
I know that a very similar question has been asked before, but I can't make it work for my project, despite many
tests and I don't understand what I'm doing wrong.
In my Maven pom.xml I've the following:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.8.5</version>
<scope>compile</scope>
</dependency>
In web.xml I reference webmvc-config.xml, and the log confirms that is loaded.
<servlet>
<servlet-name>mainServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
In webmvc-config.xml I've the following:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:annotation-driven />
My Controller is:
@Controller
public class ClassifiedController {
@RequestMapping(value = "/classified/{idClassified}", headers = "Accept=*/*",
method = RequestMethod.GET)
@ResponseBody
public final Classified getClassified(@PathVariable final int idClassified) {
...
I tried with or without the headers parameter with the same results. If I call the URL
directly with Firefox the Request Headers contain the following (checked with firebug):
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
If I use the following JQuery:
$.ajax({
url: '/classified/38001',
type: 'GET',
dataType: 'json'
});
The following headers are sent:
Accept: application/json, text/javascript, */*; q=0.01
In both cases the result is a 406 error. I don't know what else should I check to make
it work.
UPDATE: I decided to debug through Spring and I found out that Jackson was called correctly and in org.codehaus.jackson.map.ser.StdSerializerProvider the method _findExplicitUntypedSerializer contains the following code:
try {
return _createAndCacheUntypedSerializer(runtimeType, property);
} catch (Exception e) {
return null;
}
This is unfortunate because hides the source of the problem. With the debugger I found out that that exception contained a very descriptive error message:
Conflicting getter definitions for property "reminded":
ClassifiedImpl#isReminded(0 params) vs
ClassifiedImpl#getReminded(0 params)
Now that I see the error message is a silly mistake and easy to fix, but without that it wasn't that obvious. In fact, fixing the problem, leaded to a working serialization.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 DispatcherServlet-servlet.xml 中添加以下内容。
Add the following in DispatcherServlet-servlet.xml.
我在 Spring MVC 和 @RestController 注释中偶然发现了同样的错误(406:内容不可接受)。
Spring 处理程序:
观察:
http://www.host.com/stuff-acknowledgment/{id}
$id
有一个非常特殊的格式:xxxcomplicatedhashxxx.png
(或任何你能想到的扩展名)。因此:
Spring MVC 解释扩展并希望生成相同 mime 类型的结果(即使我将其定义为路径变量),这里是一个
"image/png"
MIME 类型,即使我告诉他生成 JSON。所以会抛出406异常。修复:
删除URI中的
“.png”
扩展名,或者删除PathVariable并将其放入正文中,或者在pathVariable后面添加后缀(未测试但应该也可以工作),重点是避免在 URI 末尾使用文件扩展名。PS:我知道它没有回答问题中的具体问题(更新中的解决方案),但我在搜索该问题时发现了 SO 线程,并在此处发布我的修复记录,希望它可以帮助某人未来。
I've stumbled upon the same error (406: content not acceptable) with Spring MVC and @RestController annotation.
The Spring handler:
Observation:
http://www.host.com/stuff-acknowledgment/{id}
$id
has a very particular format:xxxcomplicatedhashxxx.png
(or whatever extension you can think of).Therefore:
Spring MVC interpret the extension and want to produce a result of that same mime type (even if I define it as a path variable), here an
"image/png"
MIME type even if I tell him to produce JSON. So a 406 exception is thrown.Fix:
Remove the
".png"
extension in the URI, or remove the PathVariable and put it in the body, or add a suffix behind the pathVariable (not tested but should work as well), the point is to avoid a file extension at the end of the URI.P.S.: I know it doesn't answer the specific problem (with the solution in the update) in the question but I found that SO thread when searching for that problem and post my fix here for the record, hoping it can help someone in the future.
就 MappingJacksonJson 处理时,您需要确保 Jackson ObjectMapper 支持 用于序列化的对象类型。
In terms of the MappingJacksonJson processing, you'll need to make sure that the Jackson ObjectMapper supports your object type for serialisation.
我遇到了这个问题,因为我想要以 JSON 形式返回的对象的属性没有任何 getter 方法。杰克逊可能需要这些。添加它们后,它起作用了。
I ran into this problem because the objects that I wanted to return as JSON didn't have any getter methods for their properties. Jackson probably needs these. After adding them it worked.
虽然这个线程有点旧...
你需要添加以下内容(maven 依赖项):
org.codehaus.jacksonjackson-mapper-asl1.9.13
although this thread is a little old...
u need to add the following (maven dependency):
org.codehaus.jacksonjackson-mapper-asl1.9.13