- Spring MVC处理异常有3种方式:
- 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;
- 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
- 使用@ExceptionHandler注解实现异常处理;
项目中才有第二种异常处理方式,个人比较推荐第二种和第三种实现方式。
2. 使用SimpleMappingExceptionResolver实现异常处理
- 在Spring的配置文件applicationContext.xml中增加以下内容:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定义默认的异常处理页面,当该异常类型的注册时使用 -->
<property name="defaultErrorView" value="error"></property>
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常也页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="cn.basttg.core.exception.BusinessException">error-business</prop>
<prop key="cn.basttg.core.exception.ParameterException">error-parameter</prop>
<!-- 这里还可以继续扩展对不同异常类型的处理 -->
</props>
</property>
</bean>
- 使用SimpleMappingExceptionResolver进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但该方法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用。
3. 实现HandlerExceptionResolver 接口自定义异常处理器
public class EmvcExceptionHandler implements HandlerExceptionResolver {
private static Log log = LogFactory.getLog(EmvcExceptionHandler.class);
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) {
String rurl = request.getServletPath();
ModelAndView model = new ModelAndView();
if (rurl.lastIndexOf(".do") > 0)
model.setViewName("/commons/error/error");
else {
model.setViewName("/error");
}
//访问url
String url = request.getServletPath();
//访问的参数
Enumeration enu = request.getParameterNames();
StringBuffer params = new StringBuffer();
while (enu.hasMoreElements()) {
String paraName = (String) enu.nextElement();
params.append(paraName + "=" + request.getParameter(paraName));
}
//描述信息
String message = exception.getMessage();
//异常类型
String exceptionType = exception.getClass().getName();
//异常位置
String position = null;
ByteArrayOutputStream stackTrace = new ByteArrayOutputStream();
exception.printStackTrace(new PrintStream(stackTrace));
String content = stackTrace.toString();
Pattern pat = Pattern.compile("com(.*)\\)");
Matcher mat = pat.matcher(content);
boolean rs = mat.find();
if (rs) {
position = mat.group(1);
}
position = "com"+position+")";
XaskContext.getSystemData().saveExceptionLog(Arrays.asList(new ExceptionLog(url,params.toString(),message,exceptionType,position,new Date())));
if ((exception instanceof XaskException)) {
model.addObject("errorMsg", exception.getMessage());
log.error(exception.getMessage());
return model;
}
model.addObject("errorMsg", exception.getMessage());
model.addObject("ex", exception);
log.error("未处理异常", exception);
return model;
}
}
- 在Spring的配置文件applicationContext.xml中增加以下内容:
<bean id="exceptionHandler" class="cn.basttg.core.exception.MyExceptionHandler"/>
- 使用实现HandlerExceptionResolver接口的异常处理器进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。
4. 使用@ExceptionHandler注解实现异常处理
- 增加BaseController类,并在类中使用@ExceptionHandler注解声明异常处理,代码如下:
@ExceptionHandler
public String exp(HttpServletRequest request, Exception ex) {
System.out.println("异常捕捉||||||"+ex.getClass() + " ||||||====== " +ex.getMessage());
request.setAttribute("ex", ex);
// 根据不同错误转向不同页面
if (ex instanceof ParameterException) {
return "error-parameter";
} else {
return "error";
}
}
- 使所有需要异常处理的Controller都继承该类
- 使用@ExceptionHandler注解实现异常处理,具有集成简单、有扩展性好(只需要将要异常处理的Controller类继承于BaseController即可)、不需要附加Spring配置等优点,但该方法对已有代码存在入侵性(需要修改已有代码,使相关类继承于BaseController),在异常处理时不能获取除异常以外的数据。