我正在尝试使用Spring 3.0.6返回JSON响应,但我收到406响应“Not Acceptable”,其描述如下: “此请求标识的资源只能生成具有特征的响应 根据请求“接受”标题()不可接受。“
我知道之前已经问过a very similar question,但我不能让它为我的项目工作,尽管很多 测试,我不明白我做错了什么。
在我的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错误。我不知道还应该检查什么 它有效。
UPDATE :我决定通过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)
现在我看到错误消息是一个愚蠢的错误并且很容易修复,但没有它就不那么明显了。事实上,修复问题,导致工作序列化。
答案 0 :(得分:7)
在DispatcherServlet-servlet.xml中添加以下内容。
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter"/>
</list>
</property>
</bean>
答案 1 :(得分:7)
我在Spring MVC和@RestController注释中偶然发现了同样的错误(406:内容不可接受)。
Spring处理程序:
@RequestMapping(value = "/stuff-acknowledgment/{id}", produces ="application/json;charset=UTF-8", headers="Accept=*")
public Message acknowledgeStuff(@PathVariable("id") String id, @ModelAttribute("ack") AckBean acquittement) {
观察:
http://www.host.com/stuff-acknowledgment/{id}
$id
有一种非常特殊的格式:xxxcomplicatedhashxxx.png
(或者你能想到的任何扩展名)。 因此:
Spring MVC解释扩展并希望生成相同mime类型的结果(即使我将其定义为路径变量),这里是一个"image/png"
MIME类型,即使我告诉他生成JSON。因此抛出了406异常。
修复:
删除URI中的".png"
扩展名,或者删除PathVariable并将其放在正文中,或者在pathVariable后面添加一个后缀(未经测试但应该也可以正常工作),重点是避免使用文件URI末尾的扩展名。
答案 2 :(得分:6)
就MappingJacksonJson处理而言,您需要确保Jackson ObjectMapper支持your object type进行序列化。
答案 3 :(得分:4)
我遇到了这个问题,因为我想要作为JSON返回的对象没有任何针对其属性的getter方法。杰克逊可能需要这些。添加它们之后就可以了。
答案 4 :(得分:2)
虽然这个帖子有点旧......
你需要添加以下内容(maven依赖):
org.codehaus.jacksonjackson映射器,asl1.9.13