zoukankan      html  css  js  c++  java
  • Spring MVC 使用介绍(九)—— 异常处理

    一、概述

    Spring MVC异常处理功能的作用为:捕捉处理器的异常,并映射到相应视图

    有4种方式: 

    • SimpleMappingExceptionResolver:通过配置的方式实现异常处理,该方式简单、无侵入性,但仅能获取到异常信息
    • HandlerExceptionResolver:通过实现该接口并实例化为bean实现异常处理,该方式简单、无侵入性,并能够获取关于异常的更详细信息
    • @ExceptionHandler:通过在控制器类或控制器类的基类中添加异常处理方法,从而实现单个控制器范围的异常处理,该方法对已有代码有侵入性
    • web.xml的<error-page>标签:可通过异常类型或error-code指定异常页面

    多种方式的并存会增大维护的成本,因此异常处理方式选择其中一种,推荐使用SimpleMappingExceptionResolver,再配合web.xml中的<error-page>即可

    简单示例:

    异常类

    public class BusinessException extends RuntimeException {
    
        private String errorCode;
        
        public BusinessException(String errorCode, String msg) {
            super(msg);
            this.setErrorCode(errorCode);
        }
    
        public String getErrorCode() {
            return errorCode;
        }
    
        public void setErrorCode(String errorCode) {
            this.errorCode = errorCode;
        }
    }
    public class ParameterException extends RuntimeException {
        
        public ParameterException(String msg) {
            super(msg);
        }
    }

    控制器

    @Controller  
    public class TestController9 {  
          
        @RequestMapping(value = "/controller.do", method = RequestMethod.GET)  
        public void controller(HttpServletResponse response, Integer id) throws Exception {
            switch(id) {  
                case 1:  
                    throw new BusinessException("10", "controller10");  
                case 2:  
                    throw new BusinessException("20", "controller20");  
                default:  
                    throw new ParameterException("Controller Parameter Error");  
            }  
        }   
    }  

    配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:mvc="http://www.springframework.org/schema/mvc" 
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
               http://www.springframework.org/schema/mvc 
               http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
               http://www.springframework.org/schema/context 
               http://www.springframework.org/schema/context/spring-context-4.2.xsd">
              
    
        <mvc:annotation-driven />
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
            <property name="prefix" value="/WEB-INF/jsp/"/>  
            <property name="suffix" value=".jsp"/>  
        </bean>  
        
        <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.matt.exception.BusinessException">error-business</prop>  
                    <prop key="cn.matt.exception.ParameterException">error-parameter</prop>  
                </props>  
            </property>  
        </bean>
        
        <context:component-scan base-package="cn.matt" 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.RestController" />
        </context:component-scan>
    </beans>

    error.jsp、error-business.jsp、error-parameter.jsp

    <%@ page contentType="text/html; charset=UTF-8"%>
    <html>
    <head><title>Exception!</title></head>
    <body>
    <% Exception e = (Exception)request.getAttribute("ex"); %>
    <H2>业务错误: <%= e.getClass().getSimpleName()%></H2>
    <hr />
    <P>错误描述:</P>
    <%= e.getMessage()%>
    <P>错误信息:</P>
    <% e.printStackTrace(new java.io.PrintWriter(out)); %>
    </body>
    </html>

    启动后,访问 http://localhost:8080/myweb/controller.do?id=1 即可验证

    二、SimpleMappingExceptionResolver

    <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.matt.exception.BusinessException">error-business</prop>  
                <prop key="cn.matt.exception.ParameterException">error-parameter</prop>  
      
                <!-- 这里还可以继续扩展对不同异常类型的处理   -->
            </props>  
        </property>  
    </bean>

    使用SimpleMappingExceptionResolver进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但该方法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用

    具体如上例

    三、HandlerExceptionResolver

    @Component
    public class MyExceptionHandler implements HandlerExceptionResolver {  
          
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {  
            Map<String, Object> model = new HashMap<String, Object>();  
            model.put("ex", ex);  
              
            // 根据不同错误转向不同页面  
            if(ex instanceof BusinessException) {  
                return new ModelAndView("error-business", model);  
            }else if(ex instanceof ParameterException) {  
                return new ModelAndView("error-parameter", model);  
            } else {  
                return new ModelAndView("error", model);  
            }  
        } 
    }  

    使用实现HandlerExceptionResolver接口的异常处理器进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。

    测试方式为:在上例配置文件中注释掉SimpleMappingExceptionResolver的配置,并添加HandlerExceptionResolver的上述代码即可

    四、@ExceptionHandler

    @Controller  
    public class TestController9 {  
          
        @RequestMapping(value = "/controller.do", method = RequestMethod.GET)  
        public void controller(HttpServletResponse response, Integer id) throws Exception {
            switch(id) {  
                case 1:  
                    throw new BusinessException("10", "controller10");  
                case 2:  
                    throw new BusinessException("20", "controller20");  
                default:  
                    throw new ParameterException("Controller Parameter Error");  
            }  
        }   
        
        @ExceptionHandler  
        public String exp(HttpServletRequest request, Exception ex) {  
              
            request.setAttribute("ex", ex);  
              
            // 根据不同错误转向不同页面  
            if(ex instanceof BusinessException) {  
                return "error-business";  
            }else if(ex instanceof ParameterException) {  
                return "error-parameter";  
            } else {  
                return "error";  
            }  
        }  
    }

    使用@ExceptionHandler注解实现异常处理,具有集成简单、扩展性好、不需要附加Spring配置等优点,但该方法对已有代码存在入侵性,在异常处理时不能获取除异常以外的数据。

    测试方式为:在上例配置文件中注释掉SimpleMappingExceptionResolver的配置,并将控制器修改为上述代码即可

    五、web.xml的<error-page>标签

    对于非控制器产生的异常,如404,spring mvc的异常机制无法捕获,此类异常可在web.xml中通过<error-page>节点配置显示页面

    <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> 

    补充:

    异常输出为json字符串(而非页面)的方式如下:

    @ExceptionHandler  
    public void exp(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException {  
          
        response.setContentType("text/plain;charset=UTF-8");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("errorCode", 200);
        map.put("errorMsg", ex.getMessage());
        response.getWriter().write(JSON.toJSONString(map));
    }  

    参考:

    使用Spring MVC统一异常处理实战

    springmvc处理异常的4种方式

    Spring MVC 异常处理详解

  • 相关阅读:
    oracle基本语句
    SVM入门(六)线性分类器的求解——问题的转化,直观角度
    深入浅出KMeans算法
    SVM入门(三)线性分类器Part 2
    SVM入门(一)SVM的八股简介
    Hadoop源代码分析(五)
    用HTML5 Audio API开发游戏音乐
    Hadoop源代码分析(六)
    SVM入门(四)线性分类器的求解——问题的描述Part1
    SVM入门(二)线性分类器Part 1
  • 原文地址:https://www.cnblogs.com/MattCheng/p/9203795.html
Copyright © 2011-2022 走看看