使用@ResponseBody返回json,当Accept标头为* / *时抛出HttpMediaTypeNotAcceptableException

时间:2011-03-15 17:06:19

标签: spring spring-mvc

我正在使用spring 3.0.0。

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

有没有办法将此接受模式映射到application / 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;
}

谢谢!

3 个答案:

答案 0 :(得分:2)

从我今天收集的所有内容中,有两种方法可以解决这个问题。

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

  2. 这是我现在要解决的问题。它并不漂亮,但是当你每次都期待application / json时,它们都没有设置 / 的Accept标头。我最后将ServletResponse对象添加到我的方法中,并使用旧学校的方式直接写入输出流以绕过消息转换器并返回我的响应。


  3. @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);
        }
    }
    

    如果你有更优雅的东西,我很乐意看到它!

答案 1 :(得分:1)

我刚遇到同样的问题。我不确定它是否更优雅,但我选择做的只是返回一个字符串,然后将对象转换为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;
   }

}

答案 2 :(得分:0)

将这些依赖项包含在您的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>