Spring REST 控制器不支持媒体类型或无处理程序
Spring REST Controller Unsupported Media Type or No Handler
如果我有这样的 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
header 中使用错误的媒体类型调用此端点,然后 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
发回 spring 然后将其视为不可接受的媒体类型并调用 HttpMediaTypeExceptionHandler
异常处理程序再次说媒体类型是不可接受的。
在 Spring 中有没有办法停止进入异常处理程序的第二个循环,即使接受 header 不包含 application/problem+json
媒体类型,它也会 return 无论如何?
奇怪的是,当我将 return 语句更改为:
时它开始工作了
return new ResponseEntity<>(problem, httpStatus);
对此:
return ResponseEntity
.status(httpStatus)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(problem);
我不确定它是如何工作的,但确实如此。
如果我有这样的 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
header 中使用错误的媒体类型调用此端点,然后 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
发回 spring 然后将其视为不可接受的媒体类型并调用 HttpMediaTypeExceptionHandler
异常处理程序再次说媒体类型是不可接受的。
在 Spring 中有没有办法停止进入异常处理程序的第二个循环,即使接受 header 不包含 application/problem+json
媒体类型,它也会 return 无论如何?
奇怪的是,当我将 return 语句更改为:
时它开始工作了return new ResponseEntity<>(problem, httpStatus);
对此:
return ResponseEntity
.status(httpStatus)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(problem);
我不确定它是如何工作的,但确实如此。