首页 > 解决方案 > 根据@RequestMapping 的产生条件返回错误响应的内容类型

问题描述

我的 REST Web 服务中有自定义错误处理。我有返回 XML / JSON 作为响应的方法。在 SpringBoot 版本2.0.9上一切正常。但是在迁移到最新版本(2.2.4)之后,我的错误处理测试失败了:

Content type expected:<application/xml> but was:<application/json>
Expected :application/xml
Actual   :application/json

经过研究,我发现它与将 Spring 升级到 5.1 版本有关。文件:

错误响应的内容协商 @RequestMapping 的产生条件不再影响错误响应的内容类型。

如何在最新的 Spring 早期版本中重现行为?我只想返回产生条件中指定的错误的内容类型。

休息方法:

@PostMapping(path = "/{scriptName}", produces = { MediaType.APPLICATION_XML_VALUE })
public ResponseEntity<Object> xmlMethod(@RequestParam("payload") String payload, @PathVariable("scriptName") String scriptName) {

    Object result = service.call(payload, scriptName);
    return ResponseEntity.ok(new JsonBuilder(result).getContent());
}

@PostMapping(path = "/{scriptName}", produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Object> jsonMethod(@RequestParam("payload") String payload, @PathVariable("scriptName") String scriptName) {
    Object result = service.call(payload, scriptName);
    return ResponseEntity.ok(new JsonBuilder(result).getContent());
}

CustomRestExceptionHandler:

@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {

        HTTPErrorDTO httpError = new HTTPErrorDTO(HttpStatus.NOT_FOUND, ex.getLocalizedMessage());
        return new ResponseEntity<>(httpError, new HttpHeaders(), httpError.getStatus());
    }

    ....
    // handlers for other exceptions
}

错误 DTO:

@XmlRootElement(name = "Exception")
@XmlAccessorType(XmlAccessType.FIELD)
public class HTTPErrorDTO {

    private HttpStatus status;
    private String message;
    private List<String> errors;
}

相关主题:Spring mvc - 为 XML 和 JSON 响应配置错误处理

- -编辑

我尝试添加自定义内容协商配置。但是我的 REST API 的一个客户端向我发送 content-type = "application/x-www-form-urlencoded"并期望 application/xml 并且不发送任何接受标头。

所以我只能在方法/控制器级别决定内容类型应该是什么格式。

我可以以某种方式从控制器通知异常处理程序,应该设置哪一种内容类型?

标签: springspring-bootspring-mvcspring-restcontrollerspring-rest

解决方案


在您的CustomRestExceptionHandler中,您可以为ResponseEntity.

return ResponseEntity.status(httpError.getStatus().value())
        .contentType(MediaType.APPLICATION_XML)
        .body(httpError);

推荐阅读