详细:http://cgs1999.iteye.com/blog/1547197
1 描述
在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。
那么,能不能将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护?答案是肯定的。下面将介绍使用Spring MVC统一处理异常的解决和实现过程。
2 分析
Spring MVC处理异常有3种方式:
(1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;
(2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
(3)使用@ExceptionHandler注解实现异常处理;
我在项目中喜欢使用第二种方式:简单明了,对项目无侵入性:
在spring-mvc配置文件中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<context:component-scan base-package="com.lgy.web" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<mvc:annotation-driven/>
<!-- SpringMVC默认跳转视图 -->
<!-- <mvc:view-controller path="/" view-name="index"/> -->
<!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 控制器异常处理 -->
<bean id="exceptionHandler" class="com.lgy.web.exception.MyExceptionHandler"/>
<import resource="shiro/spring-mvc-shiro.xml"/>
</beans>
自定义异常类如下:
package com.lgy.web.exception;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
public class MyExceptionHandler implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object object, Exception e) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("exception", e);
// 根据不同错误转向不同页面
if(e instanceof UnknownAccountException) {
//用户名错误
model.put("error", "对不起,用户名错误");
return new ModelAndView("login", model);
}else if(e instanceof LockedAccountException) {
//账号被锁定异常
model.put("error", "对不起,用户名已被锁定");
return new ModelAndView("login", model);
} else if(e instanceof IncorrectCredentialsException) {
//密码错误
model.put("error", "对不起,密码错误");
return new ModelAndView("login", model);
}
return new ModelAndView("error", model);
}
}
这样每当抛出异常的时候,都会被这个自定义类接受到,通过e instanceof 异常类 做比较就能得出是抛出的什么异常,然后进行相应的判断。
对应未被捕获的异常,例如404页面找不到,500服务器类部错误等可以在web.xml中进行如下配置即可:
<!-- 出错页面定义 -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
<!-- 这里可继续增加服务器错误号的处理及对应显示的页面 -->