You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 05:03:38