【问题标题】:RestController: HTTP Status 406 - Not AcceptableRestController:HTTP 状态 406 - 不可接受
【发布时间】:2018-05-31 04:07:47
【问题描述】:

我使用“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;
    }
}

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

【问题讨论】:

  • 没有Jackson有什么办法可以完成这项工作吗?需要某事来进行序列化。如果您不想要杰克逊,请使用其他东西。 Spring MVC 还有一个GsonHttpMessageConverter
  • @SotiriosDelimanolis:您能举个例子吗?

标签: java spring-mvc


【解决方案1】:

关于 406 - 不可接受

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

produces = "application/json"

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

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

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

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

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

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

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

关于如何使用 Jsoniter 手动响应

正如这个问题的答案Does spring mvc have response.write to output to the browser directly?

您可以使用@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);
}

【讨论】:

  • 我会使用自定义 Jsoniter 消息转换器,而不是转换控制器本身的值。
  • 我对此投了反对票,因为我在问题中描述了我不想这样做(这是我目前的方法)。所以虽然我很感谢你的贡献,但这个答案绝对是不敬的
  • @tkruse:问题是我不想使用 jackson,我想使用 Jsoniter 作为配置来实现 RestController 行为。
  • @tkruse:是的,没错,但是我不想通过注释属性或直接通过 Servlet 将 json 手动写入响应流,而是想以我可以使用的方式配置 Spring 框架RestController 注解并直接在 API 中返回对象。例如我返回List&lt;String&gt;,Spring在后台根据提供的序列化框架处理序列化。
  • 为此添加了另一个答案部分。请注意,这与您的 406 http 错误无关,所以如果这没有足够的信息并且链接的问题没有帮助,也许您可​​以创建一个关于自定义 HttpMessageConverters 的新问题。
【解决方案2】:

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 开始,根据默认配置,喜爱路径扩展设置为 true,因此,如果请求 uri 有任何适当的扩展,如.htm,spring 将优先考虑扩展。在第 2 步中,我添加了 contentNegotiationManager bean 来覆盖它。

【讨论】:

    【解决方案3】:

    在我的案例中,场景是使用 Spring restTemplate.put 方法在数据库中插入 pdf 资源。

    http://${apiGateWay}/resource/provision/Test.pdf

    标题为应用程序/pdf。但我仍然收到 406 不可接受的错误。

    调试问题后发现,put request不接受带有.key的key扩展名。

    因此网址应该是,

    http://${apiGateWay}/resource/provision/Test

    【讨论】:

      猜你喜欢
      • 2019-04-30
      • 2019-12-15
      • 1970-01-01
      • 2018-07-22
      • 2019-05-05
      • 2019-11-17
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多