• SpringMVC 学习-异常处理 SimpleMappingExceptionResolver 类


    Spring3.0 对异常的处理方式总共有两种:

    一种是使用 HandlerExceptionResolver 接口,并且 Spring 已经提供默认的实现类 SimpleMappingExceptionResolver。

    第二种方法是在 Controller 内部实现,灵活性更高。

    从目前的调查结果来看,这两种方式不能共存。我们一般在项目中使用第一种方法。

    下面分别描述一下这两种使用方式:

    一、基于 HandlerExceptionResolver 接口的方式

    使用这种方式只需要实现 resolveException 方法,该方法返回一个 ModelAndView 对象,在方法内部对异常的类型进行判断,然后返回合适的 ModelAndView 对象,如果该方法返回了 null,则 Spring 会继续寻找其他的实现了 HandlerExceptionResolver 接口的 Bean。换句话说,Spring 会搜索所有注册在其环境中的实现了 HandlerExceptionResolver 接口的 Bean,逐个执行,直到返回了一个 ModelAndView 对象。

    public class CustomExceptionHandler implements HandlerExceptionResolver {  
      
        @Override  
        public ModelAndView resolveException(HttpServletRequest request,  
                HttpServletResponse response, Object object, Exception exception) {  
            if(exception instanceof IOException){  
                return new ModelAndView("ioexp");  
            }else if(exception instanceof SQLException){  
                return new ModelAndView("sqlexp");  
            }  
            return null;  
        }  
    } 

    这个类必须声明到 Spring 配置文件中,或者使用 @Component 标签,让 Spring 管理它。同时 Spring 也提供默认的实现类 SimpleMappingExceptionResolver,需要使用时只需要使用注入到 Spring 配置文件进行声明即可。自定义实现类与默认的实现类,可同时使用。

    示例如下:

    <!-- 自定义的实现类 -->
    <bean id="exceptionHandler" class="com.enh.test.CustomExceptionHandler"/>
    <!-- 默认的实现类注入 -->
    <
    bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!-- 为所有的异常定义默认的异常处理页面,exceptionMappings未定义的异常使用本默认配置 --> <property name="defaultErrorView" value="error"></property> <!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception --> <property name="exceptionAttribute" value="ex"></property> <!--
        定义需要特殊处理的异常,用类名或完全路径名作为key,异常页文件名作为值,
        将不同的异常映射到不同的页面上。
      
    --> <property name="exceptionMappings"> <props> <prop key="IOException">error/ioexp</prop> <prop key="java.sql.SQLException">error/sqlexp</prop> </props> </property> </bean>

    一个典型的异常显示界面如下:

    <html> 
    <head><title>Exception!</title></head> 
    <body> 
      <% Exception ex = (Exception)request.getAttribute("exception"); %> 
      <H2>Exception: <%= ex.getMessage();%></H2> 
      <P/> 
      <% ex.printStackTrace(new java.io.PrintWriter(out)); %> 
    </body> 
    </html> 

    exception 是在 SimpleMappingExceptionResolver 被存放到 request 中的,具体可以查看源代码。

    另外这里配置的异常显示界面均仅包括主文件名,至于文件路径和后缀已经在 viewResolver 中指定。如果找不到页面,会根据错误提示再调整页面路径。

    二、Controller 内部单独实现

    该方法需要定义在 Controller 内部,然后创建一个方法并用 @ExceptionHandler 注解来修饰用来处理异常,这个方法基本和 @RequestMapping 修饰的方法差不多,只是可以多一个类型为 Exception 的参数,@ExceptionHandler 中可以添加一个或多个异常的类型,如果为空的话则认为可以触发所有的异常类型错误。

    @Controller  
    public class ExceptionHandlerController {  
          
        @ExceptionHandler(value={IOException.class,SQLException.class})  
        public String exp(Exception ex,HttpServletRequest request) {  
            request.setAttribute("ex", ex);  
            return "/error.jsp";  
        }  
      
    }  

    三、相关问题

    HandlerExceptionResolver 和 web.xml 中配置的 error-page 会有冲突吗?

    web.xml 中配置 error-page 同样是配置出现错误时显示的页面:

    <error-page>
        <error-code>500</error-code>
        <location>/500.jsp</location>
    </error-page>

    如果 resolveException 返回了 ModelAndView,会优先根据返回值中的页面来显示。不过,resolveException 可以返回 null,此时则展示 web.xml 中的 error-page 的500状态码配置的页面。

    API 文档中对返回值的解释:

    return a corresponding ModelAndView to forward to, or null for default processing.
  • 相关阅读:
    一起来学linux:网络命令
    python网络爬虫之使用scrapy自动登录网站
    python网络爬虫之requests库 二
    一起来学linux:网络配置
    一起来学linux:日志文件
    一起来学linux:进程
    python网络爬虫之requests库
    【原创】大数据基础之Ambari(1)简介、编译安装、使用
    【原创】数据库基础之Mysql(1)常用命令
    【原创】大叔经验分享(22)securecrt连接自动断开
  • 原文地址:https://www.cnblogs.com/libra0920/p/6289848.html
Copyright © 2020-2023  润新知