【问题标题】:Spring-Returning json with @ResponseBody when the Accept header is */* throws HttpMediaTypeNotAcceptableException当 Accept 标头为 */* 时,带有 @ResponseBody 的 Spring-Returning json 会引发 HttpMediaTypeNotAcceptableException
【发布时间】:2011-07-15 23:26:17
【问题描述】:

我正在使用 spring 3.0.0。

我有一个端点,它返回一个我想序列化为 JSON 的对象。当请求带有 Accept: application/json 时,它可以正常工作。该请求当前以*/* 作为接受值。不幸的是,我无法控制请求,否则我会改变它。当收到*/* 时,它会抛出一个 HttpMediaTypeNotAcceptableException 异常。

有没有办法将此接受模式映射到应用程序/json?

这与另一个问题非常相似,但关键区别在于我需要将 Accept 标头设置为 */*Spring's Json not being resolved with appropriate response

这是我的控制器的样子:

@RequestMapping(value = "/v1/endpoint", method = RequestMethod.POST)
@ResponseBody
public EndpointResponse runEndpoint(@RequestBody String jsonData) {

    ObjectMapper mapper = new ObjectMapper();
    EndpointRequest opRequest = null;
    EndpointResponse opResponse = null;

    try {

        opRequest = mapper.readValue(jsonData, EndpointRequest.class);

        //....do stuff



    } catch (JsonParseException e) {
        return handleException(opResponse, e);
    } catch (JsonMappingException e) {
        return handleException(opResponse, e);
    } catch (IOException e) {
        return handleException(opResponse, e);
    }

    return opResponse;
}

谢谢!

【问题讨论】:

  • 您是否尝试在 runEndpoint 方法中添加 headers="Accept=/" 参数?这是一个示例:krams915.blogspot.com/2011/02/…
  • @chris 感谢您的想法。我试了一下,仍然得到 HttpMediaTypeNotAcceptableException。不过这是有道理的。 @RequestMapping 上的 headers 参数用于将请求映射到特定的 Controller 方法,但不影响 Response 转换器到 Accept mime 类型的映射。

标签: spring spring-mvc


【解决方案1】:

根据我今天收集的所有内容,有 2 个选项可以解决此问题。

  1. 编写一个 BeanPostProcessor,它将更新 MappingJacksonConverter 上支持的 mime 类型以接受 /。 (使用supportedMimeTypes 属性不起作用......见https://jira.springsource.org/browse/SPR-6214

  2. 这是我现在要使用的解决方案。它并不漂亮,但是当您每次都期望 application/json 时,也不会设置 / 的 Accept 标头。我最终将 ServletResponse 对象添加到我的方法中,并使用直接写入输出流的老式方法绕过消息转换器并返回我的响应。


@RequestMapping(value = "/v1/endpoint", method = RequestMethod.POST)
public void runEndpoint(@RequestBody String jsonData,
ServletResponse response) {

    ObjectMapper mapper = new ObjectMapper();
    EndpointRequest opRequest = null;
    EnpointResponse opResponse = null;
    StringWriter sw = new StringWriter();

    try {

        opRequest = mapper.readValue(jsonData, EndpointRequest.class);

        opResponse = ...do stff...

        mapper = new ObjectMapper();

        mapper.writeValue(sw, opResponse);

        response.setContentType("application/json");
        response.getOutputStream().write(sw.toString().getBytes());

        } catch (JsonParseException e) {
        handleException(opResponse, e, response);
        } catch (JsonMappingException e) {
        handleException(opResponse, e, response);
        } catch (IOException e) {
        handleException(opResponse, e, response);
    }
}

如果你有更优雅的东西,我很想看看!

【讨论】:

    【解决方案2】:

    我刚刚遇到了同样的问题。我不确定它是否更优雅,但我选择做的只是返回一个字符串,然后自己将对象转换为 Json。我决定将 Gson 用于 JSON 库。

    @Controller
    public class NewAbstractController  {
    
       @RequestMapping(value = "/simple", method = RequestMethod.GET)
       public @ResponseBody String SayHello()
       {
           Foo foo = new Foo();
           foo.Name = "Chris";
           foo.age = 30;
    
           Gson gson = new Gson();
           return gson.toJson(foo);
       }
    
       public class Foo implements Serializable
       {
           public String Name;
           public Integer age;
       }
    
    }
    

    【讨论】:

      【解决方案3】:

      将这些依赖项包含到您的 pom.xml 中

       <dependency>
          <groupId>org.codehaus.jackson</groupId>
          <artifactId>jackson-core-asl</artifactId>
          <version>1.9.3</version>
       </dependency>
      
       <dependency>
          <groupId>org.codehaus.jackson</groupId>
          <artifactId>jackson-mapper-asl</artifactId>
          <version>1.9.3</version>
        </dependency>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-25
        • 2021-10-05
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 2013-08-13
        相关资源
        最近更新 更多