[英]RestController: HTTP Status 406 - Not Acceptable
我使用“Jsonitter”作为 JSON 序列化框架,并且在我的项目中不使用 Maven。 我一直在通过将“Jsonitter”的结果直接写入HttpServletResponse
来在我的 restful api 中返回 JSON 对象,直到现在我发现了@RestController
属性。 来自 ASP.Net MVC 背景,我希望框架能够根据Accept
标头自动序列化我的 api 中返回的对象。 但我觉得,Spring 需要第三方序列化框架来呈现结果(即 Jackson),因为它返回HTTP Status 406 - Not Acceptable
结果。
我使用它的方式如下:
@RestController
@EnableWebMvc
public class TestApi {
@RequestMapping(value = "Test", method = RequestMethod.Get, produces = "application/json")
public List<String> letsTest(){
return myStringList;
}
}
我没有提到杰克逊,我宁愿根本不使用它,我觉得错误是由于这个原因。 没有杰克逊有没有办法完成这项工作?
由于您的控制器配置为仅在客户端请求application/json
数据时才返回响应,
produces = "application/json"
您可能会收到“406 Not Acceptable”,因为您的客户请求了其他内容/未指定任何 Accepts 标头。 您可以通过以下方式修复:
Accepts
标头*/*
如果您很懒惰)。这是您唯一的问题,您不必强制使用任何带有 Spring 的序列化框架(但如果您定义控制器方法以返回任意 bean,则需要序列化器)。 您可以编写任何字符串作为对客户的响应。
如果您想继续使用 Jsoniter,但将其移至后台,以便您的 Controller 类不再明确提及 jsoniter,则需要定义自己的自定义 HttpMessageConverter 。
你需要一些序列化器来从 Java 生成 Json。 您可以编写自定义代码,或使用 Jackson 或 Gson。 Spring 默认支持 Jackson,使用 GsonHttpMessageConverter 支持 Gson。 对于 Jackson,您当前的代码是可以的,但是您需要添加 jackson 依赖项。 对于 Gson,您需要声明转换器,网上有几个资源对此进行了说明。
就像这个问题的答案一样, spring mvc 是否有 response.write 可以直接输出到浏览器?
您可以使用@ResponseBody
编写您的回复。 由于@RestController
已经暗示@ResponseBody
,您也可以将其省略。 在这里显示它只是为了澄清:
@ResponseBody // not needed with @RestController
@RequestMapping(value = "Test", method = RequestMethod.Get, produces = "application/json")
public String letsTest() {
// Using Jsoniter JsonStream
return JsonStream.serialize(myStringList);
}
Spring 4.3.10:我使用以下设置来解决问题。
第 1 步:添加以下依赖项
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.7</version>
</dependency>
<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>
第 2 步:在 MVC DispatcherServlet 上下文配置中添加以下内容:
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false"/>
<property name="favorParameter" value="true"/>
<property name="ignoreAcceptHeader" value="false" />
</bean>
从 spring 3.2 开始,根据默认配置,favourPathExtension 设置为 true,因此如果请求 uri 有任何适当的扩展名,如.htm
,spring 将优先考虑扩展名。 在第 2 步中,我添加了 contentNegotiationManager bean 来覆盖它。
在我的案例中,场景是使用 Spring restTemplate.put 方法在数据库中插入 pdf 资源。
http://${apiGateWay}/resource/provision/Test.pdf
标题为应用程序/pdf。 但我仍然收到 406 不可接受的错误。
调试问题后发现,put request 不接受带有 . 扩大。
因此,网址应该是,
http://${apiGateWay}/resource/provision/Test
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.