推荐使用@controlleradvice+@exceptionhandler配合自定义errorresponse实体,封装timestamp(instant.now())、path(从httpservletrequest获取)、error(httpstatus.getreasonphrase())、status(http状态码),并支持按异常类型精细化返回400/404/405等状态及对应错误信息。

<p>在Spring Boot中实现统一异常处理并返回包含<code>timestamp</code>、<code>path</code>、<code>error</code>、<code>status</code>字段的响应结构,推荐使用<code>@ControllerAdvice</code> + <code>@ExceptionHandler</code>配合自定义响应体。</p> <h3>定义标准化响应实体</h3> <p>创建一个通用响应类(如<code>ErrorResponse</code>),封装异常时需返回的核心字段:</p>
-
timestamp:使用Instant.now()或LocalDateTime.now(),建议用Instant避免时区歧义 -
path:从请求上下文获取当前请求路径(通过WebRequest或HttpServletRequest) -
error:异常的简明描述(如"Bad Request"或"Internal Server Error"),可从HttpStatus获取getReasonPhrase() -
status:HTTP状态码(int类型,如400、500)
编写全局异常处理器
使用@ControllerAdvice捕获所有控制器抛出的异常,并构造ErrorResponse返回:
<code>@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(
Exception ex, WebRequest request) {
HttpStatus status = (ex instanceof HttpClientErrorException)
? ((HttpClientErrorException) ex).getStatusCode()
: HttpStatus.INTERNAL_SERVER_ERROR;
ErrorResponse errorResponse = new ErrorResponse(
Instant.now(),
request.getDescription(false), // 默认含path,也可用 request.getContextPath() + request.getServletPath()
status.getReasonPhrase(),
status.value()
);
return ResponseEntity.status(status).body(errorResponse);
}
}</code>
注意:request.getDescription(false)默认返回uri=xxx,若需纯净path,建议注入HttpServletRequest并调用getServletPath()或getRequestURI()。
补充常见异常的精细化处理
为不同异常类型提供更准确的状态码和错误信息:
-
@ResponseStatus(HttpStatus.NOT_FOUND)修饰的自定义异常(如UserNotFoundException)可单独捕获,设error="Not Found"、status=404 -
MethodArgumentNotValidException对应参数校验失败,error可取第一个校验错误的defaultMessage,status=400 -
HttpRequestMethodNotSupportedException返回error="Method Not Supported",status=405
确保响应体序列化友好
在ErrorResponse类中添加Lombok注解或手动写getter/setter,并用@JsonFormat规范时间格式:
<code>public class ErrorResponse {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
private Instant timestamp;
private String path;
private String error;
private int status;
// 构造方法、getter、setter...
}</code>
这样返回的JSON会是标准格式,例如:
{ "timestamp": "2024-06-15 14:22:33.123", "path": "/api/users/999", "error": "Not Found", "status": 404 }Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











