如何在Spring Boot 3中启用RFC 7807问题详情格式?
在Spring Boot 3中启用RFC 7807(Problem Details)错误格式
一、默认生效场景
Spring Boot 3原生支持RFC 7807规范,当你在控制器中抛出ResponseStatusException时,框架会自动返回符合规范的Problem Details格式响应,无需额外配置:
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "无效的请求参数");
返回示例:
{ "type": "about:blank", "title": "Bad Request", "status": 400, "detail": "无效的请求参数", "instance": "/api/v1/some-resource" }
二、全局启用Problem Details格式
如果要让框架自动处理的错误(如404、参数绑定失败、500等)也返回RFC 7807格式,只需添加对应配置属性:
对于Spring MVC应用
在application.properties中添加:
spring.mvc.problemdetails.enabled=true
对于Spring WebFlux应用
在application.properties中添加:
spring.webflux.problemdetails.enabled=true
开启后,默认错误(比如404)的响应会变成:
{ "type": "about:blank", "title": "Not Found", "status": 404, "detail": "No message available", "instance": "/api/v1/non-existent-resource" }
三、自定义Problem Details内容
如果需要修改默认的Problem Details字段(比如自定义type、添加额外属性),可以通过实现ErrorAttributes来扩展:
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.ProblemDetails; import org.springframework.web.context.request.WebRequest; @Configuration public class ProblemDetailsConfig { @Bean public ErrorAttributes errorAttributes() { return new DefaultErrorAttributes() { @Override public ProblemDetails getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { ProblemDetails problemDetails = super.getErrorAttributes(webRequest, options); // 替换默认的type字段 problemDetails.setType(java.net.URI.create("https://your-api-domain.com/errors/" + problemDetails.getStatus())); // 添加自定义的timestamp字段 problemDetails.setProperty("timestamp", System.currentTimeMillis()); return problemDetails; } }; } }
四、针对特定异常的自定义处理
如果需要对特定异常(如参数验证失败)添加更详细的信息,可以创建全局异常处理器:
import org.springframework.http.HttpStatus; import org.springframework.http.ProblemDetails; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; @ControllerAdvice public class GlobalExceptionHandler { // 处理参数验证异常 @ExceptionHandler(MethodArgumentNotValidException.class) public ProblemDetails handleValidationErrors(MethodArgumentNotValidException ex, WebRequest request) { ProblemDetails problemDetails = ProblemDetails.forStatusAndDetail(HttpStatus.BAD_REQUEST, "参数验证失败"); problemDetails.setInstance(request.getDescription(false).replace("uri=", "")); problemDetails.setType(java.net.URI.create("https://your-api-domain.com/errors/validation-failed")); // 添加错误字段详情 problemDetails.setProperty("invalidFields", ex.getBindingResult().getFieldErrors().stream() .map(error -> error.getField() + ": " + error.getDefaultMessage()) .toList()); return problemDetails; } // 处理所有未捕获的异常 @ExceptionHandler(Exception.class) public ProblemDetails handleAllExceptions(Exception ex, WebRequest request) { ProblemDetails problemDetails = ProblemDetails.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage()); problemDetails.setInstance(request.getDescription(false).replace("uri=", "")); problemDetails.setType(java.net.URI.create("https://your-api-domain.com/errors/internal-server-error")); return problemDetails; } }
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

