11.异常机制
1.使用 @ExceptionHandler 注解实现异常处理
2.自定义自己的异常处理器,需要实现 Spring 的异常处理接口 HandlerExceptionResolver。
3.使用 Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver。
11.1 @ExceptionHandler 局部异常处理
@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;
}
}
- 测试页面:index.jsp,这块故意将username改为usernames造成user属性为null的异常
<form action="${pageContext.request.contextPath}/user/userOS" method="post">
<div>
<label for="username">用户名:</label>
<input type="text" name="usernames" id="username">
</div>
<div>
<label for="pwd">密码:</label>
<input type="password" name="pwd" id="pwd">
</div>
<div>
<label for="email">邮件:</label>
<input type="email" name="email" id="email">
</div>
<input type="submit" value="登陆">
</form>
<body>
<h3>错误页面</h3>
错误信息:${msg}
</body>
- 测试在首页输入信息后提交,转到这个报错页面。null值,信息页面不显示数据需要在输出信息补充点null指针异常信息
-
注意:@ExceptionHandler 注解定义的方法优先级问题:例如发生的是 NullPointerException,但是声明的异常有 RuntimeException 和 Exception,这时候会根据异常的最近继承关系找到继承深度最近的那个@ExceptionHandler 注解方法,即标记了 RuntimeException 的方法。 -
被 @ExceptionHandler 标记为异常处理方法,不能在方法中设置别的形参。但是可以使用 ModelAndView 向前台传递数据。
11.2 自定义异常处理器
- 上面这种注解方式,仅能处理某个 Controller 中的异常,若需要对所有异常进行统一处理,可以用此方式
- 实现异常处理接口 HandlerExceptionResolver,可以处理处理器异常、数据绑定异常以及控制器执行时发生的异常,发生异常时,Spring MVC 会调用 resolveException() 方法,并转到 ModelAndView 对应的视图中,返回一个异常报告页面反馈给用户。
- 举例:沿用上面的例子,将第一种方式注释掉
//托管MyExceptionHandler
@Component
public class MyExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 根据不同错误转向不同页面(统一处理),即异常与View的对应关系
Map<String,Object> 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);
}
}
- 发起请求显示结果:null值,信息页面不显示数据需要在输出信息补充点null指针异常信息。
11.3 SimpleMappingExceptionResolver
- 第二种全局异常处理方式:使用 SimpleMappingExceptionResolver 来实现。它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定义默认的异常处理页面,当该异常类型注册时使用 -->
<property name="defaultErrorView" value="error"/>
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
<property name="exceptionAttribute" value="msg"/>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="NullPointerException">error</prop>
<prop key="ArithmeticException">error1</prop>
<prop key="IllegalArgumentException">error1</prop>
</props>
</property>
</bean>
11.4 方式4:@ControllerAdvice
- Spring 3.2 带来的新特性。从名字上可以看出大体意思是控制器增强。 也就是说,@controlleradvice + @ ExceptionHandler 也可以实现全局的异常捕捉
- 抽取一个异常处理类
@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<String,String> exceptionHandle(Exception ex){
Map<String,String> 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异常}
下一篇:SpringMVC-19-springmvc文件上传
|