zoukankan      html  css  js  c++  java
  • Spring Boot 中的异常处

    Spring Boot 框架异常处理有五种处理方式,从范围来说包括有全局异常捕获处理方式和局部异常捕获处 理方式
    自定义异常错误页
     在遇到异常时,Spring Boot 会自动跳到一个默认的异常页面,如请求上述 http://localhost:8080/exceptionMethod 路径时发生 500 错误,Spring Boot 会有一个默认的页面 展示给用户,如图所示

    Spring Boot 默认的异常处理机制是程序中出现了异常 Spring Boot 就会请求 /error 的 url 。
    这里以 Thymleaf 为例,Thymleaf 页面模板默认处于 classpath:/templates/ 下, 因此在该目录下创建 error.html 文件即可
    使用@ExceptionHandler注解处理局部异常
    SpringMVC 提供了@ExceptionHandler 这个注解,在 SpringBoot 里面,我们同样可以 使用它来做异常捕获。直接在对应的 Controller 里面增加一个异常处理的方法,并使用 @ExceptionHandler 标识它即可,属于局部处理异常
    @Controller
    public class ExceptionController {
        private static final Logger log = LoggerFactory.getLogger(ExceptionController.class);
        @RequestMapping("/exceptionMethod")
        public String exceptionMethod(Model model) throws Exception {
            model.addAttribute("msg", "没有抛出异常");
            int num = 1/0;
            log.info(String.valueOf(num));
            return "index";
        }
        /**
         * 描述:捕获 ExceptionController 中的 ArithmeticException 异常
         * @param model 将Model对象注入到方法中
         * @param e 将产生异常对象注入到方法中
         * @return 指定错误页面
         */
        @ExceptionHandler(value = {ArithmeticException.class})
        public String arithmeticExceptionHandle(Model model, Exception e) {
            model.addAttribute("msg","@ExceptionHandler" + e.getMessage());        log.info(e.getMessage());
            return "error";
        }
    }
    使用 @ControllerAdvice 注解处理全局异常
    实际开发中,需要对异常分门别类的进行处理,使用 @ControllerAdvice + @ExceptionHandler 注解能够处理全局异常,这种方式推荐使用,可以根据不同的异常对不 同的异常进行处理。
       使用方式:定义一个类,使用 @ControllerAdvice 注解该类,使用 @ExceptionHandler 注解方法,这里我定义了一个 GlobalException 类表示来处理全局异常,代码如下:
    
    //GlobalException.java
    @ControllerAdvice
    public class GlobalException {
        private static final Logger log = LoggerFactory.getLogger(GlobalException.class);
        /**
         * 描述:捕获 ArithmeticException 异常
         * @param model 将Model对象注入到方法中
         * @param e 将产生异常对象注入到方法中
         * @return 指定错误页面
         */
      
      @ExceptionHandler(value = {ArithmeticException.class})
        public String arithmeticExceptionHandle(Model model, Exception e) {
            model.addAttribute("msg", "@ControllerAdvice + @ExceptionHandler :" + e.getMessage());
            log.info(e.getMessage());
            return "error";
        }
    }
    如果需要处理其他异常,如 NullPointerException 异常,则只需要在 GlobalException 类 中定义一个方法使用 @ExceptionHandler(value = {NullPointerException.class}) 注解该方法, 在该方法内部处理异常就可以了。
    配置 SimpleMappingExceptionResolver 类处理异常
    通过配置 SimpleMappingExceptionResolver 类处理异常也是全局范围的,通过将 SimpleMappingExceptionResolver 类注入到 Spring 容器,代码如下:
    
    @Configuration
    public class GlobalException {
        @Bean
        public SimpleMappingExceptionResolver
        getSimpleMappingExceptionResolver(){
            SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
            Properties mappings = new Properties();
            /*
             * 参数一:异常的类型,注意必须是异常类型的全名
             * 参数二:视图名称
             */
            mappings.put("java.lang.ArithmeticException", "error");
            //设置异常与视图映射信息的
            resolver.setExceptionMappings(mappings);
            return resolver;
        }
    }
    实现 HandlerExceptionResolver 接口处理异常
    通过实现 HandlerExceptionResolver 接口处理异常,首先编写类实现 HandlerExceptionResolver 接口,代码如下:
    
    @Configuration
    public class HandlerExceptionResolverImpl implements HandlerExceptionResolver {
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                                             Exception ex) {
            ModelAndView modelAndView = new ModelAndView();
           modelAndView.addObject("msg", "实现 HandlerExceptionResolver 接口处理异常");
            //判断不同异常类型,做不同视图跳转
            if(ex instanceof ArithmeticException){
                modelAndView.setViewName("error");
            }
            return modelAndView;
        }
    }
     当然了,异常很多,比如还有 RuntimeException,数据库还有一些查询或者操作异常等 等。由于 Exception 异常是父类,所有异常都会继承该异常,所以我们可以直接拦截 Exception 异常,一劳永逸,代码如下:
    
    @ControllerAdvice
    public class GlobalException{
        private static final Logger log= LoggerFactory.getLogger(GlobalException.class);
        /**
         * 系统异常 预期以外异常
         * @param e
         * @return
         */
        @ExceptionHandler(Exception.class)
        //@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
        public JsonResult handleUnexpectedServer(Model model,Exception ex) {
            model.addAttribute("msg", "系统发生异常,请联系管理员");
            log.info(e.getMessage());
            return "error";
        }
    }
    
    实际项目中,可以把拦截 Exception 异常写在 GlobalException最下面,如果都没有找到,最后再拦截一下 Exception 异常,保证异常得到处理。
  • 相关阅读:
    Redis基础-基本数据类型
    C#特性
    C#反射
    Json序列化
    动态添加文本框并获取文本框的值
    iframe中镶嵌html页,并获取html页中的方法
    获取url中的参数
    发送邮件
    数据导入Excel表格
    处理xml模块、configparser模块、hashlib模块、subprocess模块
  • 原文地址:https://www.cnblogs.com/tszr/p/15442954.html
Copyright © 2011-2022 走看看