Spring Boot浏览器无法显示JSON错误信息,Postman正常
Spring Boot 实现浏览器与Postman统一返回JSON格式错误响应
问题场景
Spring Boot项目中,浏览器访问接口时会显示Whitelabel Error Page白标错误页,但Postman请求却能正常获取JSON格式的错误响应。需要实现浏览器也返回一致的JSON错误信息。
浏览器错误示例
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Nov 29 17:10:21 UTC 2023
There was an unexpected error (type=Not Found, status=404).
Resource Not Found
Postman返回示例
{ "timestamp": "2023-11-29T18:21:30.864+00:00", "status": 404, "error": "Not Found", "message": "Resource Not Found", "path": "/getDetails" }
问题根源
Spring Boot默认错误处理机制会根据请求的Accept头判断响应类型:
- 浏览器请求头通常包含
text/html,触发白标错误页面; - Postman等工具请求头为
application/json,返回JSON响应。
当前全局异常处理器使用response.sendError()方法,会触发容器转发到Spring Boot默认的/error端点,进而触发上述媒体类型判断逻辑,导致浏览器返回白标页。
解决方案
方案一:修改全局异常处理器,直接返回JSON对象
放弃response.sendError(),改为返回自定义错误DTO对象,通过@ResponseStatus指定状态码,确保所有请求都返回JSON。
1. 定义错误DTO类
import lombok.Data; import java.time.LocalDateTime; @Data public class ErrorResponse { private LocalDateTime timestamp; private int status; private String error; private String message; private String path; public ErrorResponse(int status, String error, String message, String path) { this.timestamp = LocalDateTime.now(); this.status = status; this.error = error; this.message = message; this.path = path; } }
2. 修改全局异常处理器
import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.validation.ConstraintViolationException; import javax.validation.ValidationException; import java.util.Set; @RestControllerAdvice @Validated public class ValidationExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) public ResponseEntity<ErrorResponse> constraintViolationException(HttpServletRequest request, ConstraintViolationException e) { StringBuilder messageBuilder = new StringBuilder(); Set<?> violations = e.getConstraintViolations(); for (Object violation : violations) { messageBuilder.append(((javax.validation.ConstraintViolation<?>) violation).getMessage()).append("\n"); } ErrorResponse errorResponse = new ErrorResponse( HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), messageBuilder.toString().trim(), request.getRequestURI() ); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); } @ExceptionHandler(ValidationException.class) public ResponseEntity<ErrorResponse> dateViolationException(HttpServletRequest request, ValidationException e) { HttpStatus status; String message = e.getMessage(); if ("Resource Not Found".equalsIgnoreCase(message)) { status = HttpStatus.NOT_FOUND; } else if ("User Not Found in the system".equalsIgnoreCase(message)) { status = HttpStatus.UNAUTHORIZED; } else { status = HttpStatus.BAD_REQUEST; } ErrorResponse errorResponse = new ErrorResponse( status.value(), status.getReasonPhrase(), message, request.getRequestURI() ); return new ResponseEntity<>(errorResponse, status); } }
方案二:配置Spring Boot强制所有错误返回JSON
无需修改异常处理器,通过配置覆盖默认错误逻辑,强制返回JSON格式。
方式1:自定义ErrorController
import jakarta.servlet.http.HttpServletRequest; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; @RestController public class CustomErrorController implements ErrorController { @RequestMapping("/error") public ResponseEntity<ErrorResponse> handleError(HttpServletRequest request) { Object status = request.getAttribute("javax.servlet.error.status_code"); String message = (String) request.getAttribute("javax.servlet.error.message"); String path = (String) request.getAttribute("javax.servlet.error.request_uri"); int statusCode = status != null ? Integer.parseInt(status.toString()) : HttpStatus.INTERNAL_SERVER_ERROR.value(); HttpStatus httpStatus = HttpStatus.valueOf(statusCode); ErrorResponse errorResponse = new ErrorResponse( statusCode, httpStatus.getReasonPhrase(), message != null ? message : "Unknown error", path != null ? path : request.getRequestURI() ); return new ResponseEntity<>(errorResponse, httpStatus); } }
方式2:配置application.properties
# 关闭白标错误页 server.error.whitelabel.enabled=false # 强制错误响应为JSON格式 server.error.content-type=application/json
效果验证
修改完成后,无论是浏览器还是Postman请求接口,都会返回统一格式的JSON错误响应。
内容的提问来源于stack exchange,提问作者Rose
相关产品推荐
相关产品推荐

