如果我有一个像这样的spring REST控制器
@PostMapping(
value = "/configurations",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public CreateConfigurationResponse createConfiguration(
@RequestBody @Valid @NotNull final CreateConfigurationRequest request) {
// do stuff
}
,客户端在Accept
标头中使用错误的媒体类型调用此终结点,然后spring抛出HttpMediaTypeNotAcceptableException
。然后,我们的异常处理程序将其捕获并构建一个Problem
(rfc-7807)错误响应
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class HttpMediaTypeExceptionHandler extends BaseExceptionHandler {
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public ResponseEntity<Problem> notAcceptableMediaTypeHandler(final HttpMediaTypeNotAcceptableException ex,
final HttpServletRequest request) {
final Problem problem = Problem.builder()
.withType(URI.create("...."))
.withTitle("unsupported media type")
.withStatus(Status.NOT_ACCEPTABLE)
.withDetail("...error stuff..")
.build();
return new ResponseEntity<>(problem, httpStatus);
}
但是由于Problem
错误响应应该以媒体类型application/problem+json
发送回去,因此弹簧将其视为不可接受的媒体类型,并再次调用HttpMediaTypeExceptionHandler
异常处理程序并说该媒体类型是不可接受的。
Spring中是否有一种方法可以停止第二个循环进入异常处理程序,即使accept标头不包含application/problem+json
媒体类型,它仍然会返回该值?
答案 0 :(得分:0)
奇怪的是,当我从以下命令更改return语句时,它开始工作:
return new ResponseEntity<>(problem, httpStatus);
对此:
return ResponseEntity
.status(httpStatus)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(problem);
我不确定这是如何工作的,但确实如此。