zoukankan      html  css  js  c++  java
  • 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进行添加和删除属性.

  • 相关阅读:
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 Cowboys
    Java实现 蓝桥杯 算法训练 Cowboys
    55. Jump Game
    54. Spiral Matrix
    50. Pow(x, n)
  • 原文地址:https://www.cnblogs.com/trekxu/p/9740078.html
Copyright © 2011-2022 走看看