我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护。
①1.Spring自带异常处理器
Spring中自带了一个异常处理器SimpleMappingExceptionResolver,它实现了HandlerExceptionResolver,使用SimpleMappingExceptionResolver需要在Spring.xml中配置以下节点
<!--参数方法名解析器--> <bean id="methodNameResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/day10Exception/"/> <property name="suffix" value=".jsp"/> </bean> <!--扫描包下所有的被标注的类--> <context:component-scan base-package="cn.happy.day10Exception"/> <!--异常处理器--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--默认错误视图--> <property name="defaultErrorView" value="error"/> <!--异常类型--> <property name="exceptionAttribute" value="ex"/> </bean>
2.自定义一个异常
//自定义异常 public class UserNameException extends Exception { //重写构造 public UserNameException() { super(); } public UserNameException(String message) { super(message); } }
3.测试程序
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class FirstController { @RequestMapping("/first") public String doFirst(String username,int age) throws Exception { //如果用户名不等于admin就出错 if(!username.equals("admin")){ throw new UserNameException("用户名错误"); } //跳转到doSecond页面 return "doSecond"; } }
②异常处理器提升版
需要在SimpleMappingExceptionResolver节点添加一个exceptionMappings属性,它是properties类型
<!--异常处理器--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--默认错误视图--> <property name="defaultErrorView" value="error"/> <!--异常类型--> <property name="exceptionAttribute" value="ex"/> <property name="exceptionMappings"> <props> <!--key:异常类型 val:出现异常后转到的页面--> <prop key="UserNameException">name</prop> <prop key="AgeException">age</prop> </props> </property> </bean>
Key值代表自定义的异常类型,value代表出现当前异常后转向的jsp页面
③自定义异常处理器
自定义异常类型处理器需要实现HandlerExceptionResolver接口
//自定义异常处理器 public class MyHandlerExceptionResolver implements HandlerExceptionResolver { /** * * @param httpServletRequest 请求 * @param httpServletResponse 响应 * @param o object对象 * @param e 返回异常类型 * @return */ public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { //创建视图模型对象 ModelAndView mv=new ModelAndView(); //错误信息使用el方式打印出错误信息 mv.addObject("ex",e); //判断异常类型 if(e instanceof UserNameException){ //如果是UserNameException异常则转到name.jsp页面 mv.setViewName("name"); } if (e instanceof AgeException){ //如果是AgeException异常则转到name.jsp页面 mv.setViewName("age"); } //返回视图对象 return mv; } }
处理器类
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * Created by Administrator on 2018/3/30. */ @Controller public class FirstController { @RequestMapping("/first") public String doFirst(String username,int age) throws Exception { if(!username.equals("admin")){ throw new UserNameException("用户名错误"); } if(age>60){ throw new AgeException("年龄错误"); } return "doSecond"; } }
最后配置Spring.xml
配置自定义的异常处理器的bean
<!--参数方法名解析器--> <bean id="methodNameResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/day11selfException/"/> <property name="suffix" value=".jsp"/> </bean> <!--扫描包下所有的被标注的类--> <context:component-scan base-package="cn.happy.day11selfException"/> <!--自定义异常处理器--> <bean class="cn.happy.day11selfException.MyHandlerExceptionResolver"/>
④使用注解方式注册异常处理器
@ExceptionHandler()用来捕获系统发生的异常,默认捕获所有异常。它只有一个参数,是一个Class类型的数组,可以用来捕获class类型的异常。
自定义异常类
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; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Created by Administrator on 2018/3/30. */ @Controller public class FirstController { //只捕获UserNameException和AgeException类型的异常 @ExceptionHandler({UserNameException.class,AgeException.class}) public ModelAndView resolveException( Exception e) { ModelAndView mv=new ModelAndView(); mv.addObject("ex",e); //判断异常类型是否为UserNameException异常 if(e instanceof UserNameException){ //发生异常后要转到的页面 mv.setViewName("name"); } //判断异常类型是否为AgeException异常 if (e instanceof AgeException){ //跳转页面 mv.setViewName("age"); } //返回模型视图对象 return mv; } //URL @RequestMapping("/first") public String doFirst(String username,int age) throws Exception { if(!username.equals("admin")){ throw new UserNameException("用户名错误"); } if(age>60){ throw new AgeException("年龄错误"); } return "doSecond"; } }
Spring.xml配置
<!--参数方法名解析器--> <bean id="methodNameResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/day11selfException/"/> <property name="suffix" value=".jsp"/> </bean> <!--扫描包下所有的被标注的类--> <context:component-scan base-package="cn.happy.day12annotationException"/>