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

Spring Boot REST服务异常时返回白标错误页而非JSON的问题

解决Spring Boot REST服务异常仍返回Whitelabel Error Page的问题

看起来你已经找对了方向——用@ExceptionHandler或@ControllerAdvice处理异常,但断点触发却还是返回白标签页面,大概率是你的异常处理方法的返回逻辑有问题,或者存在隐藏的配置干扰。我来给你梳理几个最可能的原因和解决办法:

1. 异常处理方法返回值类型错误

这是最常见的坑!如果你的处理方法返回的是String或ModelAndView,Spring会把它当成视图名称去寻找对应的页面,而不是直接返回JSON。

❌ 错误示例:

@ExceptionHandler(RuntimeException.class)
public String handleRuntimeException(RuntimeException e) {
    return "发生错误:" + e.getMessage();
}

这个写法会让Spring去查找名为发生错误:xxx的视图,找不到就返回白标签页面。

✅ 正确写法:返回ResponseEntity<自定义错误对象>或直接返回POJO(因为@RestController或@ControllerAdvice配合@ResponseBody会自动序列化为JSON):

// 先定义一个错误响应DTO
@Data
public class ApiError {
    private String message;
    private int statusCode;
    private LocalDateTime timestamp;
}

// 在@RestController内的@ExceptionHandler
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<ApiError> handleRuntimeException(RuntimeException e) {
    ApiError error = new ApiError();
    error.setMessage(e.getMessage());
    error.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
    error.setTimestamp(LocalDateTime.now());
    
    return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}

// 或者用@ControllerAdvice全局处理
@RestControllerAdvice // 等价于@ControllerAdvice + @ResponseBody
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiError> handleAllExceptions(Exception e) {
        ApiError error = new ApiError();
        error.setMessage("服务器内部错误");
        error.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        error.setTimestamp(LocalDateTime.now());
        
        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

2. 未处理404等特定异常

默认情况下,Spring Boot不会对404(NoHandlerFoundException)抛出异常,而是直接返回白标签页面。如果你的问题是404时出现白标签,需要先开启抛出404异常的配置:

在application.properties中添加:

# 开启404时抛出异常
spring.mvc.throw-exception-if-no-handler-found=true
# 禁用静态资源映射(避免静态资源未找到也触发404异常)
spring.web.resources.add-mappings=false

然后在你的异常处理方法中捕获NoHandlerFoundException:

@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<ApiError> handle404(NoHandlerFoundException e) {
    ApiError error = new ApiError();
    error.setMessage("请求路径不存在:" + e.getRequestURL());
    error.setStatusCode(HttpStatus.NOT_FOUND.value());
    error.setTimestamp(LocalDateTime.now());
    
    return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}

3. 检查白标签页面的配置干扰

有时候即使异常处理逻辑正确,server.error.whitelabel.enabled=true的默认配置可能会抢占响应(虽然理论上异常处理方法优先级更高,但不排除特殊情况)。可以尝试关闭白标签:

server.error.whitelabel.enabled=false

关闭后,如果异常没被处理,会返回原始的HTTP错误响应,但你的异常处理方法应该已经拦截了所有异常,所以不会有问题。

4. 确认响应的Content-Type是JSON

确保你的异常处理方法返回的响应头中Content-Type是application/json。可以显式指定:

@ExceptionHandler(Exception.class)
@Produces(MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ApiError> handleAllExceptions(Exception e) {
    // ... 构建错误对象
    return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}

或者在ResponseEntity中手动设置headers:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<>(error, headers, HttpStatus.INTERNAL_SERVER_ERROR);

最后再检查一个点:异常处理方法的优先级

如果你的项目中有多个异常处理类(比如多个@ControllerAdvice),确保你期望的处理方法优先级最高。可以用@Order注解指定优先级:

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public class GlobalExceptionHandler {
    // ... 处理方法
}

按照上面的步骤排查,应该能解决你的问题——毕竟断点已经触发,说明异常已经被捕获,只是返回的响应没被正确序列化为JSON而已。

内容的提问来源于stack exchange,提问作者Toro Boro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:41:46