• SpirngBoot--错误消息的定制


      在SpringBoot中发生了4xx 5xx之类的错误,SpringBoot默认会发一个/error的请求,该请求由BasicErrorController处理,即在SpringBoot中错误处理也是由Controller负责的。该Controller种主要有两个方法,分别用来返回HTML页面和JSon数据,具体返回何种数据由请求的头信息来确定。

        @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
        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) ? modelAndView : new ModelAndView("error", model);
        }
    
        @RequestMapping
        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<>(body, status);
        }

      在返回HTML的方法中,需要返回一个ModelAndView对象,该对象由resolveErrorView方法生成。resolveErrorView方法调用DefaultErrorViewResolver方法生成ModelAndView对象。具体的顺序是

    • 如果模板引擎可用则在template目录下error下根据错误的代码4xx 5xx寻找对应的页面
    • 如果模板引擎不可用则去static目录下error下根据错误代码寻找页面
    • 如果都没有就返回默认的页面

    简单的自定义过程

      直接把错误页面放在static/error下,页面是静态的,不能从渲染从后端取来的数据

      错误页面放在templates/error下,可使用模板语言取出数据

    完整的自定义过程

      一个完整的错误页面定制应该符合以下标准

    • 可以根据请求的不同返回json数据或者ModelAndView对象即html页面
    • 能够把后端的数据携带到页面上
    • 能够处理自定义异常

      首先自定义异常,随便定义的异常,继承RuntimeException。

    package com.xwk.exception;
    
    public class UserNotExistException extends RuntimeException {
        public UserNotExistException() {
            super("用户不存在");
        }
    }

      编写Controller抛出异常

        @RequestMapping("hello")
        @ResponseBody
        public String hello(){
    
            if (true) {
                throw  new UserNotExistException();
            }
            return "hello world";
        }

      实现自定义异常处理应该分为两步

    • 能够根据异常的类型做出不同的处理,即根据异常的类型返回不同的数据
    • 能够把返回的数据渲染出来

      

    根据类型捕获异常

        前面提到SpringBoot在异常发生的时候会发一个请求,需要一个Controller来像处理正常请求一样处理异常,在SpringBoot中异常处理的思路跟请求处理的思路是一样的。这里使用ControllerAdvice,并使用@ExceptionHandler注解表明该方法处理异常的类型,ExceptionHandler的作用和RequestMapping一样,SpringBoot会根据异常的类型找到处理该异常的方法。在handleUserNotFoundException方法上标注ExceptionHandler(UserNotExistException.class)后,所有抛出UserNotExistException的请求都会来到handleUserNotFoundException方法,这样我们的第一步已经完成的一半。

      之所以说只完成的一半是因为这些数据还没有传给视图解析对象,传递的方法是通过reqiest域,把存放需要在前端显示的数据的map放在request域中,并设置该错误的状态码。

    @ControllerAdvice
    public class MyExceptionHandler {
        @ExceptionHandler(UserNotExistException.class)
        private String handleUserNotFoundException(Exception e, HttpServletRequest request){
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("message","hghah");
            hashMap.put("status","500");
            request.setAttribute("ext",hashMap);
            request.setAttribute("javax.servlet.error.status_code",500);
    
            return "forward:/error";
        }
    }

    解析自定义异常数据   

      这部分代码可以看做是固定的,无论定义何种异常都要把下面这段代码加进去。

    public class ErrorAttributes extends DefaultErrorAttributes {
        @Override
        public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
            Map<String, Object> map = super.getErrorAttributes(webRequest,includeStackTrace);
            Map<String, Object> ext = (Map<String, Object>)webRequest.getAttribute("ext", 0);
            map.put("ext",ext);
    
            return map;
        }
    }
  • 相关阅读:
    中綴表達式求值的兩種方法
    两次bfs求树的直径的正确性
    感染linux脚本程序技术
    C# 动态代码执行
    中秋写了个狼吃羊的智力游戏
    做一个让人喜欢的人
    MySQL数据库安全配置指南
    用 VS 2005 生成 .NET 1.1 程序
    防止入侵和攻击的主要技术措施
    .NETZ 原理分析
  • 原文地址:https://www.cnblogs.com/AshOfTime/p/10917756.html
Copyright © 2020-2023  润新知