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

标签 spring spring-mvc

我使用的是 spring 3.0.0。

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

有没有办法将此接受模式映射到 application/json?

这与另一个问题非常相似,但主要区别是我需要将 Accept header 设置为 */*Spring's Json not being resolved with appropriate response

这是我的 Controller 的样子:

@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;
}

谢谢!

最佳答案

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

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

  2. 这是我现在要采用的解决方案。这并不漂亮,但是当您每次都期望 application/json 时,设置 / 的 Accept header 也不是很好。我最终将 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);
    }
}

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

关于当 Accept header 为 */* 时,Spring 使用 @ResponseBody 返回 json 抛出 HttpMediaTypeNotAcceptableException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5315288/

相关文章:

java - 在 spring IOC 中找出 bean 创建的顺序

java - Spring JPA Repository保存不插入数据库

java - @NotNull 注释在 Spring boot 应用程序中不起作用

java - Spring DateTime Conversion服务异常

java - 通过 RMI : any sense? 访问 session 范围的 bean

java - Spring注入(inject)的资源总是空的

java - Spring Data 未更新最新数据

Spring AOP : How to read path variable value from URI template in aspect?

java - Spring MVC + Tiles + Spring Security = 请求的资源不可用

java - http路径的处理方法不明确?