- 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),在异常处理时不能获取除异常以外的数据。