Gradle版Spring Boot项目@ControllerAdvice与@ExceptionHandler失效问题
问题描述
搭建了一个Gradle版简易Spring Boot项目,异常处理功能完全失效。尝试两种方式均未生效:
- 在@Controller层级通过@ExceptionHandler处理异常
- 通过@ControllerAdvice实现全局异常处理
怀疑是否因Gradle项目导致该问题,相关代码如下:
Controller类
@org.springframework.stereotype.Controller public class Controller { @GetMapping(value="/test") public String testController(){ // return "Test me"; throw new NullPointerException(); } @ExceptionHandler(value=NullPointerException.class) public String handleNPE(Exception e){ return "Test NPE"; } }
Controller Advice类
package MyController; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice public class advice { @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleNPE(Exception e){ return "Caught by advisor"; } }
build.gradle
plugins { id 'org.springframework.boot' version '2.7.2' id 'io.spring.dependency-management' version '1.0.12.RELEASE' id 'java' id 'org.springframework.experimental.aot' version '0.12.1' }
Application类
package com.example.springdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Import; @SpringBootApplication @Import(MyController.advice.class) public class SpringDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringDemoApplication.class, args); } }
解决方案
1. 修正组件扫描范围
@SpringBootApplication默认扫描启动类所在包(com.example.springdemo)及其子包,而全局异常处理类advice在MyController包,不在默认扫描范围内。虽然使用了@Import,但更可靠的做法是:
- 调整包结构,将所有业务类(包括Controller、Advice)放到
com.example.springdemo或其子包下; - 或者在启动类上显式指定扫描范围:
@SpringBootApplication(scanBasePackages = {"com.example.springdemo", "MyController"})
2. 明确返回值类型
@Controller下的方法返回字符串默认是视图名称,如果没有对应的视图模板(如Thymeleaf、JSP),会返回404而非预期的字符串内容。解决方式二选一:
- 给异常处理方法添加
@ResponseBody注解,直接返回字符串:
@ExceptionHandler(value=NullPointerException.class) @ResponseBody public String handleNPE(Exception e){ return "Test NPE"; }
- 将
@Controller替换为@RestController,默认所有方法返回响应体而非视图。
3. 移除实验性AOT插件
使用的org.springframework.experimental.aot是Spring的实验性提前编译插件,在Spring Boot 2.7.2版本中可能存在兼容性问题,导致异常处理逻辑未被正确加载。修改build.gradle移除该插件:
plugins { id 'org.springframework.boot' version '2.7.2' id 'io.spring.dependency-management' version '1.0.12.RELEASE' id 'java' // 移除AOT插件 }
4. 规范异常处理方法参数
Controller中的handleNPE方法参数为Exception e,但@ExceptionHandler指定的是NullPointerException,建议将参数类型改为NullPointerException,避免不必要的类型转换:
@ExceptionHandler(value=NullPointerException.class) @ResponseBody public String handleNPE(NullPointerException e){ return "Test NPE"; }
内容的提问来源于stack exchange,提问作者Akash Tyagi
相关产品推荐
相关产品推荐

