美文网首页
sprint-mvc-9-异常处理

sprint-mvc-9-异常处理

作者: liangxifeng833 | 来源:发表于2018-01-22 20:25 被阅读26次

    一.概念

    • Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括Handler 映射、数据绑定以及目标方法执行时发生的异常.
    • SpringMVC 提供的 HandlerExceptionResolver 的实现类


      Paste_Image.png
    Paste_Image.png

    二.举例

    1. SpringMVCTestNew.java 控制器
        /**
         * 1. 在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象
         * 2. @ExceptionHandler 方法的入参中不能传入 Map. 若希望把异常信息传导页面上, 需要使用 ModelAndView 作为返回值
         * 3. @ExceptionHandler 方法标记的异常有优先级的问题. (优先会找与出现异常最接近的异常来处理)
         * 4. @ControllerAdvice: 如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常, 
         * 则将去 @ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常. 
         */
        @ExceptionHandler({ArithmeticException.class})
        public ModelAndView handlerArithmeticException(Exception ex)
        {
            ModelAndView mv = new ModelAndView("error");
            mv.addObject("exception", ex);
            System.out.println("[出现了算数异常] : " + ex);
            return mv;
        }
        
        /**
         * 测试springMVC对于异常的处理
         */
        @RequestMapping("/testExceptionHandlerReslover")
        public String testExceptionHandlerReslover(@RequestParam(value="i") Integer i)
        {
            System.out.println("param i value = " + (10/i));
            return "success";
        }
    
    1. 新建 error.jsp
        <h4>Error Page</h4>
        <p>exception = ${requestScope.exception}</p>
    
    1. 访问: http://localhost:8081/spring-mvc-2/testExceptionHandlerReslover?i=0
      因为目标方法被除数为0,出现算数异常,所以在java控制台输出:
    [出现了算数异常] : java.lang.ArithmeticException: / by zero
    

    前台页面输出:

    Error Page
    
    exception = java.lang.ArithmeticException: / by zero
    
    1. 此时如果想让所有控制器handler都需要处理异常,则需要自己定义类实现, 以下是自己定义的 HandlerException, (注意: 如果在Handler控制器中能找到@ExceptionHandler注释的方法,则优先执行该方法)
    package com.atguigu.springmvc.tests;
    
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.servlet.ModelAndView;
    /**
     * @ControllerAdvice: 如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常, 
     * 则将去 @ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常. 
     * 如果在Handler控制器中能找到@ExceptionHandler注释的方法,则优先执行该方法
     * @author lxf
     */
    @ControllerAdvice
    public class HandlerException {
      @ExceptionHandler({ArithmeticException.class})
      public ModelAndView handlerArithmeticException(Exception ex)
      {
          ModelAndView mv = new ModelAndView("error");
          mv.addObject("exception", ex);
          System.out.println("--->[出现了算数异常] : " + ex);
          return mv;
      }
    }
    

    使用@ResponseStatus 注解

    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolverHandlerExceptionResolver 接口的实现类, 负责使用@ResponseStatus 注解将HTTP状态码返回.
    @ResponseStatus 注解可以作用在类和方法上

    • 作用在类上, 新建异常类UserNameNotMatchPasswordException
    package com.atguigu.springmvc.tests;
    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.ResponseStatus;
    /**
     * 自定义异常类
     * @author lxf
     *
     */
    @ResponseStatus(value=HttpStatus.FORBIDDEN, reason=";用户名和密码不匹配")
    public class UserNameNotMatchPasswordException extends RuntimeException {
        private static final long serialVersionUID = 1L;
    }
    
    • SpringMVCTestNew 控制器中写方法
        /**
         * 测试 @ResponseStatus 注解, 将http状态码返回客户端
         * @param i
         * @return
         */
        @RequestMapping("/testResponseStatusExceptionResolver")
        public String testResponseStatusExceptionResolver(@RequestParam("i") int i)
        {
            if(i == 13)
            {
                throw new UserNameNotMatchPasswordException();
            }else
            {
                System.out.println("testResponseStatusExceptionResolver...");
            }
            return "success";
        }
    
        /**
         * 测试 @ResponseStatus 注解, 将http状态码返回客户端
         * @param i
         * @return
         */
        @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="您访问的页面不存在!")
        @RequestMapping("/testResponseStatusExceptionResolver")
        public String testResponseStatusExceptionResolver(@RequestParam("i") int i)
        {
            if(i == 13)
            {
                throw new UserNameNotMatchPasswordException();
            }else
            {
                System.out.println("testResponseStatusExceptionResolver...");
            }
            return "success";
        }
    
    • 访问测试:


      Paste_Image.png

    DefaultHandlerExceptionResolver 处理springMVC指定的异常返回对应Http状态

    • springMVCTestNew 控制器中新增测试目标方法
        /**
         * 测试异常处理DefaultHandlerExceptionResolver处理springMVC指定的异常返回对应Http状态
         * 该处理器必须是post方式请求,如果请求方式为get那么会通过DefaultHandlerExceptionResolver处理
         * @return
         */
        @RequestMapping(value="/testDefaultHandlerExceptionResolver", method=RequestMethod.POST)
        public String testDefaultHandlerExceptionResolver()
        {
            System.out.println("testDefaultHandlerExceptionResolver");
            return "success";
        }
    
    • 如果在浏览器中请求以上方法,则会抛出异常


      Paste_Image.png

    SimpleMappingExceptionResolver

    对所有异常进行统一处理, 可以使用
    SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常

    • 配置springmvc.xml
         <!-- 配置SimpleMappingExceptionResolver类映射异常 -->
         <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <!-- 可以在对应jsp访问的异常属性定义名称, 默认=exception -->
            <property name="exceptionAttribute" value="ex"></property>
            <!-- 将异常映射到对应的 error.jsp 页面中 -->
            <property name="exceptionMappings">
                <props>
                    <!-- 映射数组越界异常到 error.jsp 页面中 -->
                    <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
                </props>
            </property>
         </bean>
    
    • SpringMVCTestNew 控制器中新增测试方法
        /**
         * 测试SimpleMappingExceptionResolver映射指定异常到对应页面
         * 如果页面传递的参数是20 ,超出数组边界, 回抛出数组越界异常, 
         * 在springmvc.xml文件中配置映射关系
         * @param i
         * @return
         */
        @RequestMapping("/testSimpleMappingExceptionResolver")
        public String testSimpleMappingExceptionResolver(@RequestParam("i") int i)
        {
            String[] arr = new String[10];
            String val = arr[i];
            System.out.println("testSimpleMappingExceptionResolver val = " + val);
            return "success";
        }
    
    • error.jsp 页面中打印异常
        <h4>Error Page</h4>
        <p>exception = ${requestScope.ex}</p>
    
    Error Page
    exception = java.lang.ArrayIndexOutOfBoundsException: 20
    

    点击查看代码练习

    相关文章

      网友评论

          本文标题:sprint-mvc-9-异常处理

          本文链接:https://www.haomeiwen.com/subject/tebnrxtx.html