Spring Boot如何避免暴露后端异常细节?@ControllerAdvice未生效处理
Spring Boot 隐藏异常细节返回通用错误消息的解决方案
问题原因
访问不存在的端点或格式无效的路径时,Spring Boot默认返回包含异常类细节的响应,这会暴露后端技术栈信息。你用@ControllerAdvice捕获异常无效,是因为这类异常(如NoHandlerFoundException)是在DispatcherServlet匹配控制器之前抛出的,不属于控制器层的异常,因此无法被@ControllerAdvice捕获。
解决方案
方案1:自定义ErrorController(推荐)
Spring Boot默认通过BasicErrorController处理全局错误请求,你可以自定义实现ErrorController接口,完全接管错误响应逻辑:
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 javax.servlet.http.HttpServletRequest; @RestController public class CustomErrorController implements ErrorController { @RequestMapping("/error") public ResponseEntity<String> handleError(HttpServletRequest request) { // 获取请求的状态码,根据不同状态返回对应消息 Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); if (statusCode != null && statusCode == HttpStatus.NOT_FOUND.value()) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("请求的资源不存在"); } else { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("服务器内部错误"); } } }
方案2:通过配置文件快速隐藏异常细节
如果不需要自定义复杂逻辑,直接修改配置文件即可关闭异常栈暴露,并设置通用错误消息:
application.properties 配置:
# 禁止在错误响应中返回异常栈信息 server.error.include-stacktrace=never # 设置全局通用错误消息 server.error.message=服务器内部错误 # 指定错误请求的处理路径(默认就是/error) server.error.path=/error
application.yml 配置:
server: error: include-stacktrace: never message: 服务器内部错误 path: /error
方案3:开启控制器层捕获404异常
如果希望用@ControllerAdvice捕获404异常,需要先开启Spring MVC抛出NoHandlerFoundException的配置,再在全局异常处理器中捕获:
- 添加配置:
# 开启当找不到处理器时抛出异常 spring.mvc.throw-exception-if-no-handler-found=true # 关闭静态资源映射,避免静态资源请求触发404异常 spring.web.resources.add-mappings=false
- 修改全局异常处理器:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.NoHandlerFoundException; @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(NoHandlerFoundException.class) public ResponseEntity<String> handleNotFound(NoHandlerFoundException ex) { // 记录异常日志 System.err.println("请求路径不存在: " + ex.getRequestURL()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body("请求的资源不存在"); } @ExceptionHandler(Exception.class) public ResponseEntity<String> handleGeneralException(Exception ex) { System.err.println("服务器内部错误: " + ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("服务器内部错误"); } }
内容的提问来源于stack exchange,提问作者tusharRawat
相关产品推荐
相关产品推荐

