在 Spring 引导中抛出 ResponseStatusException 时,响应中不包含异常消息
Exception message not included in response when throwing ResponseStatusException in Spring Boot
我的 Spring 引导应用程序提供以下 REST 控制器:
@RestController
@RequestMapping("/api/verify")
public class VerificationController {
final VerificationService verificationService;
Logger logger = LoggerFactory.getLogger(VerificationController.class);
public VerificationController(VerificationService verificationService) {
this.verificationService = verificationService;
}
@GetMapping
public void verify(
@RequestParam(value = "s1") String s1,
@RequestParam(value = "s2") String s2) {
try {
verificationService.validateFormat(s1, s2);
} catch (InvalidFormatException e) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
}
万一 validateFormat()
抛出 InvalidFormatException
客户端得到正确的 HTTP 400。默认的 JSON 响应正文看起来像这样:
{
"timestamp": "2020-06-18T21:31:34.911+00:00",
"status": 400,
"error": "Bad Request",
"message": "",
"path": "/api/verify"
}
message
值始终为空,即使我像这样对其进行硬编码也是如此:
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "some string");
这是例外情况class:
public class InvalidFormatException extends RuntimeException {
public InvalidFormatException(String s1, String s2) {
super(String.format("Invalid format: [s1: %s, s2: %s]", s1, s2));
}
}
此行为已随 Spring Boot 2.3 更改并且是有意的。有关详细信息,请参阅 release notes。
在 application.properties
中设置 server.error.include-message=always
可解决此问题。
设置server.error.include-message=always
公开内部异常消息,这可能是生产环境中的问题。
另一种方法是使用 ExceptionHandler
。在这里您可以控制传输给客户端的内容:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<String> handleBadRequestException(ResponseStatusException ex) {
// if you want you can do some extra processing with message and status of an exception
// or you can return it without any processing like this:
return new ResponseEntity<>(ex.getMessage(), ex.getStatus());
}
}
我的 Spring 引导应用程序提供以下 REST 控制器:
@RestController
@RequestMapping("/api/verify")
public class VerificationController {
final VerificationService verificationService;
Logger logger = LoggerFactory.getLogger(VerificationController.class);
public VerificationController(VerificationService verificationService) {
this.verificationService = verificationService;
}
@GetMapping
public void verify(
@RequestParam(value = "s1") String s1,
@RequestParam(value = "s2") String s2) {
try {
verificationService.validateFormat(s1, s2);
} catch (InvalidFormatException e) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
}
万一 validateFormat()
抛出 InvalidFormatException
客户端得到正确的 HTTP 400。默认的 JSON 响应正文看起来像这样:
{
"timestamp": "2020-06-18T21:31:34.911+00:00",
"status": 400,
"error": "Bad Request",
"message": "",
"path": "/api/verify"
}
message
值始终为空,即使我像这样对其进行硬编码也是如此:
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "some string");
这是例外情况class:
public class InvalidFormatException extends RuntimeException {
public InvalidFormatException(String s1, String s2) {
super(String.format("Invalid format: [s1: %s, s2: %s]", s1, s2));
}
}
此行为已随 Spring Boot 2.3 更改并且是有意的。有关详细信息,请参阅 release notes。
在 application.properties
中设置 server.error.include-message=always
可解决此问题。
设置server.error.include-message=always
公开内部异常消息,这可能是生产环境中的问题。
另一种方法是使用 ExceptionHandler
。在这里您可以控制传输给客户端的内容:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<String> handleBadRequestException(ResponseStatusException ex) {
// if you want you can do some extra processing with message and status of an exception
// or you can return it without any processing like this:
return new ResponseEntity<>(ex.getMessage(), ex.getStatus());
}
}