一、问题背景
为了自定义后端返回异常,在代码中使用了全局异常处理器如下:
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value = BusinessException.class)
public ResultBody BusineeExceptionHandle(BusinessException e, HttpServletRequest request){
String path = request.getRequestURI();
logger.error("发生业务异常!原因是:{},请求路径是:{}",e.getErrorMsg(),path);
return ResultBody.error(e.getErrorCode(), e.getErrorMsg());
}
@ExceptionHandler(value = Exception.class)
public ResultBody handleSystemException(Exception e, HttpServletRequest request){
String path = request.getRequestURI();
logger.error("发生系统异常!请求路径是:{},原因是:",path,e);
return ResultBody.error(ResCode.RES_9999);
}
}
Controller层有一个按照名称查找商品的接口:
@RestController
@RequestMapping("/inventory/products")
@Slf4j
public class ProductController {
@Autowired
ProductService productService;
// 根据名称查找产品 @RequestParam表示需要在url路径中出现该参数 searchByName?name
@GetMapping("/searchByName")
public ResultBody getProductByName(@RequestParam String name) {
return ResultBody.success(productService.getProductsByName(name));
}
二、问题
按照商品名称查找,调用get方法,发送http://localhost:8080/inventory/products/searchByName?name=草莓的请求
数据库中没有草莓的数据,因此触发异常,但是日志开始循环调用路径
2025-01-05 23:10:42 [http-nio-8080-exec-4] ERROR c.e.c.GlobalExceptionHandler - 发生业务异常!原因是:查询商品表为空,请求路径是:/inventory/products/searchByName
2025-01-05 23:10:42 [http-nio-8080-exec-4] WARN o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolved [com.example.util.BusinessException]
2025-01-05 23:10:44 [http-nio-8080-exec-4] ERROR c.e.c.GlobalExceptionHandler - 发生系统异常!请求路径是:/inventory/products/inventory/products/searchByName,原因是:
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource inventory/products/inventory/products/searchByNa
2025-01-05 23:10:45 [http-nio-8080-exec-4] ERROR c.e.c.GlobalExceptionHandler - 发生系统异常!请求路径是:/inventory/products/inventory/products/inventory/products/inventory/products/searchByName,原因是:
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource inventory/products/inventory/products/inventory/products/inventory/products/searchByName.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
···
可以看到刚开始报错没有问题,后面就开始报错NoResourceFoundException,说明请求的url路径不对。根据打出来的日志,发现后面的每次请求都是inventory/products/searchByName不断叠加/inventory/products
三、问题排查
排查了一下午(chat也没给我解决,是一个个试出来的),发现是没加@ResponseBody注解,如果不加这个注解,spring会将则返回值作为默认视图名去解析,返回值通常解析为跳转路径,控制器返回的时候路径会变为(在当前路径的上一级路径上追加路径),而这个视图是不存在的。
参考资料:https://cloud.tencent.com/developer/article/2090325
四、问题解决
加@ResponseBody注解或者将@ControllerAdive改成@RestControllerAdvice
五、反思
- 对SpringMVC不够了解
- 对@ResponseBody有了进一步理解