一:SpringMvc中常见异常处理三种方式
1:使用 SpringMvc 中的异常处理器SimpleMappingExceptionResolver
2:使用自定义异常处理器
3:使用异常处理注解
二:异常处理方式一
SimpleMappingExceptionResolver
当程序运行过程中出现异常,我们可以让SpringMvc跳转到指定的jsp中
1:自定义一个异常
package com.doaoao.myexception;
public class MyException extends Exception {
public MyException(){
super();
}
public MyException(String message){
super(message);
}
}
2:定义一个Controller,在该Controller中抛出自定义异常和系统异常
package com.doaoao.controller;
import com.doaoao.myexception.MyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ExceptionController {
@RequestMapping("/myException.do")
public ModelAndView myException(String name)throws Exception{
ModelAndView mv = new ModelAndView();
if("doaoao".equals(name)){
throw new MyException("抛出自定义异常");
}
if(!"doaoao".equals(name)){
throw new Exception("系统异常");
}
return mv;
}
}
3:修改配置文件中的内容 springmvc.xml
<!--异常处理-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="com.doaoao.myexception.MyException">error/MyError</prop>
</props>
</property>
<property name="defaultErrorView" value="error/error"/>
<property name="exceptionAttribute" value="ex"/>
</bean>
<!-- 配置中内容说明 -->
<property name="exceptionMappings">
<props>
<prop key="com.doaoao.myexception.MyException">error/MyError</prop>
</props>
</property>
1:key="com.doaoao.myexception.MyException":指定异常的全名,值为当发生异常时响应的路径名称
2:error/MyError:当发生异常时响应的jsp路径,如果配置视图解析器,会使用视图解析器中的目录和后缀
3:<property name="defaultErrorView" value="error/error"/>:指定默认异常响应页面,当发生的异常不是
exceptionMappings中定义的异常时,则使用默认异常响应页面
4:<property name="exceptionAttribute" value="ex"/>:捕获到的异常对象,该对象一般用于响应的页面中使用,
可在响应页面利用el表达式获取value中的值
在浏览器中访问:
http://localhost:8080/_01exception_war_exploded/myException.do?name=hahah
http://localhost:8080/_01exception_war_exploded/myException.do?name=doaoao
三:自定义异常处理器
但我们在捕获异常之前做出处理操作,例如将异常写入日志文件中,若有多个异常要进行捕获,者段代码就会有冗余现象出现
可以通过定义异常处理器来解决该问题,如果发生异常,会自动执行接口中的方法 resolveException()
1:定义Controller类(与上方代码相同)
package com.doaoao.controller;
import com.doaoao.myexception.MyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ExceptionController {
@RequestMapping("/myException.do")
public ModelAndView myException(String name)throws Exception{
ModelAndView mv = new ModelAndView();
if("doaoao".equals(name)){
// 处理相关操作
throw new MyException("抛出自定义异常");
}
if(!"doaoao".equals(name)){
// 处理相关操作
throw new Exception("系统异常");
}
return mv;
}
}
2:定义异常处理器
package com.doaoao.myexception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView mv = new ModelAndView();
mv.addObject("ex", e);
// 默认处理页面
mv.setViewName("error/error");
// 判断e是否是MyException
if (e instanceof MyException) {
// 处理捕获异常后的操作
// 设置跳转页面
mv.setViewName("error/MyError");
}
return mv;
}
}
3:修改配置文件 springmvc.xml
<bean class="com.doaoao.myexception.MyExceptionResolver"/>
四:使用注解处理异常
使用注解 @ExceptionHandler 可以将一个方法指定为异常处理方法,该注解具有一个参数为value,value的值为一个Class数组,Class数组用于指定处理异常的类,当Controller中抛出的异常在这个Class数组中的时候才会调用该异常处理方法
而被注解的异常处理方法,其返回值可以是 ModelAndView、String,或 void,方法名随意,方法参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会自动为这些方法参数赋值
package com.doaoao.controller;
import com.doaoao.myexception.MyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ExceptionController {
@RequestMapping("/myException.do")
public ModelAndView myException(String name)throws Exception{
ModelAndView mv = new ModelAndView();
if("doaoao".equals(name)){
// 当抛出 MyException 时会被下方定义的 handlerException 处理
throw new MyException("抛出自定义异常");
}
if(!"doaoao".equals(name)){
throw new Exception("系统异常");
}
return mv;
}
@ExceptionHandler(MyException.class)
public ModelAndView handlerException(Exception ex){
ModelAndView mv = new ModelAndView();
mv.addObject("ex", ex);
mv.setViewName("/error/MyError");
return mv;
}
}
# 当Controller中抛出异常为 MyException 时会被方法 handlerException 处理,但如果其它的Controller中抛出异常 MyException 时不会被该方法受理的,解决该问题的方法就是定义一个单独处理异常方法的Controller,然后让其它的Controller继承该 Controller,但继承是单继承的,继承了该Controller就不能在继承其它的
1:定义一个基类
package com.doaoao.controller;
import com.doaoao.myexception.MyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* 异常处理基类
*/
@Controller
public class ExceptionController {
// 处理MyException异常的方法
@ExceptionHandler(MyException.class)
public ModelAndView handleMyException(Exception ex) {
ModelAndView mv = new ModelAndView();
mv.addObject("ex", ex);
mv.setViewName("/error/MyError");
return mv;
}
// 其他异常处理,注解中不用写value属性(默认)
@ExceptionHandler
public ModelAndView handleException(Exception ex) {
ModelAndView mv = new ModelAndView();
mv.addObject("ex", ex);
mv.setViewName("/error/error");
return mv;
}
}
2:定义Controller 继承 ExceptionController
@Controller
@RequestMapping("/user")
public class newController extends ExceptionController {
@RequestMapping("/addUser.do")
public ModelAndView addUser(Exception ex,String name) throws Exception{
ModelAndView mv = new ModelAndView();
if ("doaoao".equals(name)) {
throw new MyException("抛出自定义异常");
}
return mv;
}
}
...