在 Spring MVC 应用的开发中,不可避免会遇到一些异常,我们常常需要捕获这些异常来防止程序挂掉
springmvc提供了3中异常处理办法:
1.使用 @ExceptionHandler 注解实现异常处理
2.自定义自己的异常处理器,需要实现 Spring 的异常处理接口 HandlerExceptionResolver。
3.使用 Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver。
这种方式只能处理指定控制器中的异常。
实际使用时需要在控制器中创建一个处理异常的方法,然后用此注解去标注它(非标注产生异常的方法)。然后在这个控制器中其他的方法出现异常,异常若是在这个注解处理范围内的(处理范围有这个注解值指定),会通过这个处理方式进行处理
举例:
编写控制器:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/userOS")
public String userOS(User user,Model model){
model.addAttribute("msg",JSON.toJSONString(user));
if (user.getUsername().equals("andmin")) {
model.addAttribute("msg",user.getUsername());
}
return "result";
}
@RequestMapping
@ExceptionHandler({ArithmeticException.class,NullPointerException.class,IllegalArgumentException.class})
public ModelAndView exceptionHandle(Exception ex){
System.out.println("打印异常信息:" + ex.getLocalizedMessage()+"||"+ex.getMessage());
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg",ex.getLocalizedMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
错误页面
错误信息:${msg}
注意:@ExceptionHandler 注解定义的方法优先级问题:例如发生的是 NullPointerException,但是声明的异常有 RuntimeException 和 Exception,这时候会根据异常的最近继承关系找到继承深度最近的那个@ExceptionHandler 注解方法,即标记了 RuntimeException 的方法。
被 @ExceptionHandler 标记为异常处理方法,不能在方法中设置别的形参。但是可以使用 ModelAndView 向前台传递数据。
//托管MyExceptionHandler
@Component
public class MyExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 根据不同错误转向不同页面(统一处理),即异常与View的对应关系
Map model = new HashMap<>();
//org.springframework.web.servlet.ModelAndVie注意返回的ModelAndVie类型
model.put("msg",ex.getMessage());
if (ex instanceof ArithmeticException) {
return new ModelAndView("error", model);
}else if(ex instanceof NullPointerException){
return new ModelAndView("error2", model);
}
return new ModelAndView("result", model);
}
}
error
error1
error1
@ControllerAdvice标注在类上,通过“basePackages”能够说明处理哪些路径下的异常。
@ExceptionHandler(value = 异常类型.class)标注在方法上
/**
* 管理的controller(这个包下的controller都会被管理)
*/
@Slf4j
@RestControllerAdvice(basePackages="com.zk.controller")
public class MyExceptionHandler2 {
@ExceptionHandler({ArithmeticException.class,NullPointerException.class,IllegalArgumentException.class})
public Map exceptionHandle(Exception ex){
Map map=new HashMap<>();
map.put("msg",ex.getLocalizedMessage()+"异常");
log.error("数据校验出现问题{},异常类型{}",ex.getMessage(),ex.getClass());
System.out.println(map.toString());
return map;
}
}
[ERROR] 2022-07-09 14:12:41,848 method:com.zk.exceptionconfig.MyExceptionHandler2.exceptionHandle(MyExceptionHandler2.java:31)
数据校验出现问题null,异常类型class java.lang.NullPointerException
{msg=null异常}