小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
java异常的全局处理和局部处理
使用@ControllerAdvice 拦截异常并统一处理
@ControllerAdvice注解简介
- 通过
@ControllerAdvice注解可以将对于控制器的全局配置放在同一个位置。 - 注解了
@Controller的类的方法可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上。 @ControllerAdvice注解将作用在所有注解了@RequestMapping的控制器的方法上@ExceptionHandler:用于全局处理控制器里的异常。
使用例子
- 创建MyControllerAdvice,并添加 @ControllerAdvice注解。
@ControllerAdvice
public class MyControllerAdvice {
//全局异常捕捉处理
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Map errorHandler(Exception ex) {
Map map = new HashMap();
map.put("code", 100);
map.put("msg", ex.getMessage());
return map;
}
//拦截捕捉自定义异常 MyException.class
@ResponseBody
@ExceptionHandler(value = MyException.class)
public Map myErrorHandler(MyException ex) {
Map map = new HashMap();
map.put("code", ex.getCode());
map.put("msg", ex.getMsg());
return map;
}
}
- 编写自定义异常类
public class MyException extends RuntimeException {
public MyException(String code, String msg) {
this.code = code;
this.msg = msg;
}
private String code;
private String msg;
// getter & setter
}
- controller中抛出异常进行测试
@RestController
public class ExController {
@RequestMapping("/home/ex2")
public String home() throws Exception {
// throw new Exception("程序异常");
throw new MyException("101", "自定义异常");
}
}
- 测试
启动应用,访问:http://localhost:8080/home/ex ,正常显示以下json内容,证明自定义异常已经成功被拦截。
{"msg":"自定义异常","code":"101"}
异常的局部处理
在实际生产环境中,我们经常会碰到有多种形式的出参的项目,如果都统一使用同一种异常捕获方式,可能会导致报错时候出参不符合请求方要求,因此,我们除了可以设置全局异常捕获之外,也可以单独的针对某个模块的接口进行异常捕获。
@RestController
public class ExController {
@RequestMapping("/home/ex2")
public String home() throws Exception {
// throw new Exception("程序异常");
throw new MyException("101", "自定义异常");
}
//此模块异常捕捉处理
@ResponseBody
@ExceptionHandler(value = Exception.class)
public String errorHandler(Exception ex) {
Map map = new HashMap();
map.put("code", 100);
map.put("msg", ex.getMessage());
return JSONObject.toJSONString(map);
}
}
上面这段代码中,异常捕获的作用域只在ExController中,这样避免返回其他类型的出参。