-
使用 @ ExceptionHandler 注解
-
实现 HandlerExceptionResolver 接口
-
使用 @controlleradvice 注解
1. 使用 @ ExceptionHandler 注解
使用该注解有一个不好的地方就是:进行异常处理的方法必须与出错的方法在同一个Controller里面,可以看到,这种方式最大的缺陷就是不能全局控制异常。每个类都要写一遍。
@Controller public class UserController { /** * 模拟 NullPointerException * @return */ @RequestMapping("/show1") public String showInfo(){ String str = null; str.length(); return "index"; } /** * 模拟 ArithmeticException * @return */ @RequestMapping("/show2") public String showInfo2(){ int a = 10/0; return "index"; } /** * java.lang.ArithmeticException * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视图的指定 * 参数 Exception e:会将产生异常对象注入到方法中 */ @ExceptionHandler(value={java.lang.ArithmeticException.class}) public ModelAndView arithmeticExceptionHandler(Exception e){ ModelAndView mv = new ModelAndView(); mv.addObject("error", e.toString()); mv.setViewName("error1"); return mv; } /** * java.lang.NullPointerException * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视 图的指定 * 参数 Exception e:会将产生异常对象注入到方法中 */ @ExceptionHandler(value={java.lang.NullPointerException.class}) public ModelAndView nullPointerExceptionHandler(Exception e){ ModelAndView mv = new ModelAndView(); mv.addObject("error", e.toString()); mv.setViewName("error2"); return mv; } }
2. 使用 @controlleradvice 注解+@ExceptionHandler
上文说到 @ ExceptionHandler 需要进行异常处理的方法必须与出错的方法在同一个Controller里面。那么当代码加入了 @ControllerAdvice,则不需要必须在同一个 controller 中了。这也是 Spring 3.2 带来的新特性。从名字上可以看出大体意思是控制器增强。 也就是说,@controlleradvice + @ ExceptionHandler 也可以实现全局的异常捕捉。
请确保此WebExceptionHandle 类能被扫描到并装载进 Spring 容器中
@ControllerAdvice public class GlobalException { /** * java.lang.ArithmeticException * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视图的指定 * 参数 Exception e:会将产生异常对象注入到方法中 */ @ExceptionHandler(value={java.lang.ArithmeticException.class}) public ModelAndView arithmeticExceptionHandler(Exception e){ ModelAndView mv = new ModelAndView(); mv.addObject("error", e.toString()+" -- advice"); mv.setViewName("error1"); return mv; } /** * java.lang.NullPointerException * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视 图的指定 * 参数 Exception e:会将产生异常对象注入到方法中 */ @ExceptionHandler(value={java.lang.NullPointerException.class}) public ModelAndView nullPointerExceptionHandler(Exception e){ ModelAndView mv = new ModelAndView(); mv.addObject("error", e.toString()+" -- advice"); mv.setViewName("error2"); return mv; } }
如果 @ExceptionHandler 注解中未声明要处理的异常类型,则默认为参数列表中的异常类型。所以还可以写成这样:
@ControllerAdvice
public class GlobalExceptionHandler { @ExceptionHandler() @ResponseBody String handleException(Exception e){ return "Exception Deal! " + e.getMessage(); } }
控制器中就只有业务处理的代码了
@Controller public class UserController { /** * 模拟 NullPointerException * @return */ @RequestMapping("/show1") public String showInfo(){ String str = null; str.length(); return "index"; } /** * 模拟 ArithmeticException * @return */ @RequestMapping("/show2") public String showInfo2(){ int a = 10/0; return "index"; } }
3.实现 HandlerExceptionResolver 接口
项目中的异常需要统一处理,正常情况下,需要提前准备好一个错误页面,当项目出错了,将该页面展示给用户。
@Component //注意该类需要交给Spring容器管理
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object obj,Exception ex) {
System.out.println(ex.getMessage());
ModelAndView mv = new ModelAndView();
mv.setViewName("/error.jsp");
return mv;
}
}