• SpringMVC-18-异常机制


    11.异常机制

    • 在 Spring MVC 应用的开发中,不可避免会遇到一些异常,我们常常需要捕获这些异常来防止程序挂掉

    • springmvc提供了3中异常处理办法:

    1.使用 @ExceptionHandler 注解实现异常处理

    2.自定义自己的异常处理器,需要实现 Spring 的异常处理接口 HandlerExceptionResolver。

    3.使用 Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver。

    11.1 @ExceptionHandler 局部异常处理

    • 这种方式只能处理指定控制器中的异常。

    • 实际使用时需要在控制器中创建一个处理异常的方法,然后用此注解去标注它(非标注产生异常的方法)。然后在这个控制器中其他的方法出现异常,异常若是在这个注解处理范围内的(处理范围有这个注解值指定),会通过这个处理方式进行处理

    • 举例:

    • 编写控制器:

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @RequestMapping("/userOS")
        public String userOS(User user,Model model){
            model.addAttribute("msg",JSON.toJSONString(user));
            if (user.getUsername().equals("andmin")) {
                model.addAttribute("msg",user.getUsername());
            }
            return "result";
        }
        @RequestMapping
        @ExceptionHandler({ArithmeticException.class,NullPointerException.class,IllegalArgumentException.class})
        public ModelAndView exceptionHandle(Exception ex){
            System.out.println("打印异常信息:" + ex.getLocalizedMessage()+"||"+ex.getMessage());
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("msg",ex.getLocalizedMessage());
            modelAndView.setViewName("error");
            return modelAndView;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 测试页面:index.jsp,这块故意将username改为usernames造成user属性为null的异常
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 错误页面:error.jsp
    
    

    错误页面

    错误信息:${msg}
    • 1
    • 2
    • 3
    • 4
    • 测试在首页输入信息后提交,转到这个报错页面。null值,信息页面不显示数据需要在输出信息补充点null指针异常信息

    在这里插入图片描述

    • 控制台输出:打印异常信息:null||null
    • 注意:@ExceptionHandler 注解定义的方法优先级问题:例如发生的是 NullPointerException,但是声明的异常有 RuntimeException 和 Exception,这时候会根据异常的最近继承关系找到继承深度最近的那个@ExceptionHandler 注解方法,即标记了 RuntimeException 的方法。

    • 被 @ExceptionHandler 标记为异常处理方法,不能在方法中设置别的形参。但是可以使用 ModelAndView 向前台传递数据。

    11.2 自定义异常处理器

    • 上面这种注解方式,仅能处理某个 Controller 中的异常,若需要对所有异常进行统一处理,可以用此方式
    • 实现异常处理接口 HandlerExceptionResolver,可以处理处理器异常、数据绑定异常以及控制器执行时发生的异常,发生异常时,Spring MVC 会调用 resolveException() 方法,并转到 ModelAndView 对应的视图中,返回一个异常报告页面反馈给用户。
    • 举例:沿用上面的例子,将第一种方式注释掉
    //托管MyExceptionHandler
    @Component
    public class MyExceptionHandler implements HandlerExceptionResolver {
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            // 根据不同错误转向不同页面(统一处理),即异常与View的对应关系
            Map model = new HashMap<>();
            //org.springframework.web.servlet.ModelAndVie注意返回的ModelAndVie类型
            model.put("msg",ex.getMessage());
            if (ex instanceof ArithmeticException) {
                return new ModelAndView("error", model);
            }else if(ex instanceof NullPointerException){
                return new ModelAndView("error2", model);
            }
            return new ModelAndView("result", model);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 发起请求显示结果:null值,信息页面不显示数据需要在输出信息补充点null指针异常信息。

    在这里插入图片描述

    11.3 SimpleMappingExceptionResolver

    • 第二种全局异常处理方式:使用 SimpleMappingExceptionResolver 来实现。它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。
    
        
        
        
        
        
        
            
                error
                error1
                error1
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 测试情况和前面2种一致。

    11.4 方式4:@ControllerAdvice

    • Spring 3.2 带来的新特性。从名字上可以看出大体意思是控制器增强。 也就是说,@controlleradvice + @ ExceptionHandler 也可以实现全局的异常捕捉
    • 抽取一个异常处理类

    @ControllerAdvice标注在类上,通过“basePackages”能够说明处理哪些路径下的异常。
    @ExceptionHandler(value = 异常类型.class)标注在方法上

    /**
     * 管理的controller(这个包下的controller都会被管理)
     */
    @Slf4j
    @RestControllerAdvice(basePackages="com.zk.controller")
    public class MyExceptionHandler2 {
    
        @ExceptionHandler({ArithmeticException.class,NullPointerException.class,IllegalArgumentException.class})
        public Map exceptionHandle(Exception ex){
            Map map=new HashMap<>();
            map.put("msg",ex.getLocalizedMessage()+"异常");
            log.error("数据校验出现问题{},异常类型{}",ex.getMessage(),ex.getClass());
            System.out.println(map.toString());
            return map;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 测试运行:测试工具和控制台

    在这里插入图片描述

    [ERROR] 2022-07-09 14:12:41,848 method:com.zk.exceptionconfig.MyExceptionHandler2.exceptionHandle(MyExceptionHandler2.java:31)
    数据校验出现问题null,异常类型class java.lang.NullPointerException
    {msg=null异常}

    下一篇:SpringMVC-19-springmvc文件上传

  • 相关阅读:
    i++ 和 ++i原理
    电商小程序09活动管理
    自动控制原理8.4---描述函数法
    6.前端·新建子模块与开发(常规开发)
    854. 相似度为 K 的字符串 BFS
    三、肺癌检测-肺癌检测代码项目文件准备
    【排序】详解冒泡排序
    JavaWeb之JSON、AJAX
    四入进博会,优衣库围绕科技可持续演绎“服装进化论”
    L1-015 跟奥巴马一起画方块(分数 15)
  • 原文地址:https://blog.csdn.net/weixin_42045639/article/details/125880257