-
在JavaEE 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。
-
SpringMvc 对于异常处理这块提供了支持,通过SpringMvc提供的全局异常处理机制,能够将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护。
- Spring MVC 处理异常有3 种方式
1.使用Spring MVC 提供的简单异常处理SimpleMappingExceptionResolver;
2.实现Spring 的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
3.使用@ExceptionHandler 注解实现异常处理;
接下来我们就来简单的看看这三种异常处理方式并看下优缺点:
1.使用Spring MVC 提供的简单异常处理SimpleMappingExceptionResolver;
在servlet-context中配置SimpleMappingExceptionResolver 对象,并创建error异常网页
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"></property>
<property name="exceptionAttribute" value="ex"></property>
<property name="exceptionMappings">
<props>
<prop key="com.wy.exception.BusinessException">error</prop>
<prop key="com.wy.base.ParamsException">error</prop>
</props>
</property>
</bean>
其特点:集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但该方法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用
2.实现Spring 的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
@Component
public class MyExceptionHandler implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,Object handle, Exception e) {
// 创建一个ModelAndView
ModelAndView mv = new ModelAndView();
mv.setViewName("error");// 设置默认错误页面
mv.addObject("ex",e.getMessage());//设置默认错误信息
if(e instanceof ParamException){
mv.setViewName("param_error");
ParamException ex = (ParamException) e;
mv.addObject("ex",ex.getMessage());
}
第二种的处理方式相比较第一种来说,除了具有集成简单、有良好的扩展性、***对已有代码没有入侵性***等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。
此方法在使用时也切记, 不要忘了加注解@Component,否则项目不能识别.
3.使用@ExceptionHandler 注解实现异常处理;
先写一个父类, 在父类中用@ExceptionHandler 注解实现异常处理 , 然后子类去继承父类, 子类也就拥有所有父类的异常处理功能 .
页面处理器继承BaseController
public class BaseController {
@ExceptionHandler
public String exec(HttpServletRequest request, HttpServletResponse response, Exception e){
request.setAttribute("ex",e.getMessage());
if(e instanceof ParamException){
ParamException ex = (ParamException) e;
request.setAttribute("ex", ex.getMessage());
return "param_error";
}
if(e instanceof BusinessException){
BusinessException ex = (BusinessException) e;
request.setAttribute("ex", ex.getMessage());
return "business_error";
}
return "error";
}
}
使用@ExceptionHandler 注解实现异常处理,具有集成简单、有扩展性好(只需要将要异常处理的Controller 类继承于BaseController 即可)、不需要附加Spring 配置等优点,***但该方法对已有代码存在入侵性(需要修改已有代码,使相关类继承于BaseController),***在异常处理时不能获取除异常以外的数据。并且在Java中只支持单继承, 不支持多继承 , 无法再去继承其他的类了, 条件相对比较苛刻 .
最后 , 对于我们未能捕获的异常, 我们也是最好要进行处理的 .
未捕获异常的处理
对于Unchecked Exception 而言,由于代码不强制捕获,往往被忽略,如果运行期产生了Unchecked Exception,而代码中又没有进行相应的捕获和处理,则我们可能不得不面对尴尬的404、500……等服务器内部错误提示页面。
我们需要一个全面而有效的异常处理机制。目前大多数服务器也都支持在Web.xml 中通过(Websphere/Weblogic)或者(Tomcat)节点配置特定异常情况的显示页面。修改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>