繁体   English   中英

RestController:HTTP 状态 406 - 不可接受

[英]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;
    }
}

我没有提到杰克逊,我宁愿根本不使用它,我觉得错误是由于这个原因。 没有杰克逊有没有办法完成这项工作?

关于 406 - 不可接受

由于您的控制器配置为仅在客户端请求application/json数据时才返回响应,

produces = "application/json"

您可能会收到“406 Not Acceptable”,因为您的客户请求了其他内容/未指定任何 Accepts 标头。 您可以通过以下方式修复:

  • 修复您的客户请求以提供Accepts标头
  • 更改注释以接受您的客户发送的任何内容(包括*/*如果您很懒惰)。

这是您唯一的问题,您不必强制使用任何带有 Spring 的序列化框架(但如果您定义控制器方法以返回任意 bean,则需要序列化器)。 您可以编写任何字符串作为对客户的响应。

关于如何在后台使用 Jsoniter 响应

如果您想继续使用 Jsoniter,但将其移至后台,以便您的 Controller 类不再明确提及 jsoniter,则需要定义自己的自定义 HttpMessageConverter

关于如何在没有 Jsoniter 的情况下做出响应

你需要一些序列化器来从 Java 生成 Json。 您可以编写自定义代码,或使用 Jackson 或 Gson。 Spring 默认支持 Jackson,使用 GsonHttpMessageConverter 支持 Gson。 对于 Jackson,您当前的代码是可以的,但是您需要添加 jackson 依赖项。 对于 Gson,您需要声明转换器,网上有几个资源对此进行了说明。

关于如何使用 Jsoniter 手动响应

就像这个问题的答案一样, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM