• 009 错误处理


    一 .概述

      在springboot之中,为我们的默认的错误处理进行了默认的配置,本此我们来看看错误处理的方式.


    二 .错误处理的原理

      我们首先找到错误的动配置类之中.

    @Configuration
    @ConditionalOnWebApplication
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
    // Load before the main WebMvcAutoConfiguration so that the error View is available
    @AutoConfigureBefore(WebMvcAutoConfiguration.class)
    @EnableConfigurationProperties(ResourceProperties.class)
    public class ErrorMvcAutoConfiguration {

    我们发现配置信息应该在ResourceProperties在中.

    我们现在看看这个自动配置向容器之中添加了什么组件.

        @Bean
        @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
        public DefaultErrorAttributes errorAttributes() {
            return new DefaultErrorAttributes();
        }

    添加了一个错误属性的组件.

    @Bean
        @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
        public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
            return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
                    this.errorViewResolvers);
        }

    添加了一个基本的错误处理器组件.

    @Bean
        public ErrorPageCustomizer errorPageCustomizer() {
            return new ErrorPageCustomizer(this.serverProperties);
        }

    添加一个错误页的组件.

      @Bean
        public static PreserveErrorControllerTargetClassPostProcessor preserveErrorControllerTargetClassPostProcessor() {
            return new PreserveErrorControllerTargetClassPostProcessor();
        }

    添加了一个PostProcessor组件.

    @Configuration
        static class DefaultErrorViewResolverConfiguration {
    
            private final ApplicationContext applicationContext;
    
            private final ResourceProperties resourceProperties;
    
            DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext,
                    ResourceProperties resourceProperties) {
                this.applicationContext = applicationContext;
                this.resourceProperties = resourceProperties;
            }
    
            @Bean
            @ConditionalOnBean(DispatcherServlet.class)
            @ConditionalOnMissingBean
            public DefaultErrorViewResolver conventionErrorViewResolver() {
                return new DefaultErrorViewResolver(this.applicationContext,
                        this.resourceProperties);
            }
    
        }

    上面配置了一个错误视图解析器.

    当我们的系统之中出现了异常,比如4XX或者5XX的时候,首先会找到一个错误的页面进行处理.

    我们可以从下面看到就是去了/error错误的页面.

        @Value("${error.path:/error}")
        private String path = "/error";

    然后就是错误处理器进行处理了.

    @Controller
    @RequestMapping("${server.error.path:${error.path:/error}}")
    public class BasicErrorController extends AbstractErrorController {

    我们发现这个错误处理器正好处理的就是/error的请求.

    这样就会进行下面的两个处理方式.

    @RequestMapping(produces = "text/html")
        public ModelAndView errorHtml(HttpServletRequest request,
                HttpServletResponse response) {
            HttpStatus status = getStatus(request);
            Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
                    request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
            response.setStatus(status.value());
            ModelAndView modelAndView = resolveErrorView(request, response, status, model);
            return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
        }
    
        @RequestMapping
        @ResponseBody
        public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
            Map<String, Object> body = getErrorAttributes(request,
                    isIncludeStackTrace(request, MediaType.ALL));
            HttpStatus status = getStatus(request);
            return new ResponseEntity<Map<String, Object>>(body, status);
        }

    其中,一个就是处理页面的错误,另外一个就是处理其他设备的请求错误.

    那么,这些错误信息都存放在哪里了呢?

    DefaultErrorAttributes这个组件帮助我们存放了错误的信息.


    三.自定义错误信息

    [1]页面请求

      springboot会帮助我们将浏览器的请求转换到4xx.html或者5xx.html页面之中,这个页面需要存在在error文件夹下面.

    看下面的实验:

      我们在我们的templates的error里面定义两个页面,一个是4xx.html页面,另外一个就是5xx.html页面.

    当我们使用浏览器访问的时候,就会根据错误跳转到不同的页面上.[这个需要视图解析器的支持].

    通过这种方式,我们就能完成页面请求的显示了.

    [2]在上面我们说到,我们将异常信息存放在DefaultErrorAttributes之中.

    另外我们可以使用@ControllerAdvice中添加一个HandlerException进行处理,但是这种方式无法区分是页面请求,还是json请求.

    我们就需要进行判断.

    我们可以根据produces进行判断,或者我们使用请求转发到/error的请求路径上.

    [3]如果需要自定义错误的信息,我们就向容器之中添加一个DefaultErrorAttributes就可以了.


    四 .自定义的实例  

    @Component
    public class ExceptionHandlerConfig implements HandlerExceptionResolver {
    
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) {
            // 在这里我们能够完成异常的解析工作,这是比较重要的.
            
            // 重定向到springboot为我们做的一个错误处理器.
            ModelAndView mv = new ModelAndView("forword:/error");
            return mv;
        }
    
    }

    我们首先定义一个异常解析器,这个异常解析器的核心就是需要将请求转发到/error之中,这样我们就能使用springboot的默认的错误处理机制.

    @Component
    public class ErrorAttributesEnhance extends DefaultErrorAttributes{
    
        @Override
        public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
             
            // 获取父类之中的错误的属性
             Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
             //然后我们可以对这个map进行处理,添加或者删除
             return errorAttributes;
        }
        
    }

    添加一个异常属性处理存储器,我们可以调用父类获取一些错误的信息,然后可以对这个map进行添加和删除属性.

  • 相关阅读:
    Quartz.NET 2.0 学习笔记(1) :Quartz.NET简介
    Quartz.NET 2.0 学习笔记(5) :实例创建Windows服务实现任务调度
    Quartz.NET 2.0 学习笔记(2) :和1.0的几点不同
    C#实现网页正文提取算法ok
    网页正文提取的思路
    sql getdate() 时间格式设置
    分页,静态程序asp实现,php同理
    网页正文抽取能用的抽取代码java
    泛采集技术
    查询一个数据表中的数据并插入到另一个数据表
  • 原文地址:https://www.cnblogs.com/trekxu/p/9740078.html
Copyright © 2020-2023  润新知