在 Spring Boot 中抛出 ResponseStatusException 时,响应中不包含异常消息

Rob*_*uch 40 spring-boot spring-restcontroller

我的 Spring Boot 应用程序提供以下 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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果validateFormat()抛出,InvalidFormatException客户端会得到一个正确的 HTTP 400。然而,默认的 JSON 响应正文如下所示:

{
    "timestamp": "2020-06-18T21:31:34.911+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "",
    "path": "/api/verify"
}
Run Code Online (Sandbox Code Playgroud)

message即使我像这样对其进行硬编码,该值也始终为空:

throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "some string");
Run Code Online (Sandbox Code Playgroud)

这是异常类:

public class InvalidFormatException extends RuntimeException {

    public InvalidFormatException(String s1, String s2) {
        super(String.format("Invalid format: [s1: %s, s2: %s]", s1, s2));
    }
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*uch 70

这种行为在 Spring Boot 2.3 中发生了变化,并且是有意为之。有关详细信息,请参阅发行说明

设置server.error.include-message=alwaysapplication.properties解决此问题。


mic*_*czy 7

设置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());
    }
}
Run Code Online (Sandbox Code Playgroud)