Halo(十一)

Spring Boot 继承 AbstractErrorController 实现全局异常处理

@RequestMapping("${server.error.path:${error.path:/error}}"):

    如果在 application 中设置了 server.error.path,就映射该值。

    如果 error.path 有值就映射该值。

    否则映射 /error。

    优先级=> server.error.path > error.path > /error


自定义错误页面:

    Spring Boot 将所有的错误默认映射到/error, 实现ErrorController。

    Html静态页面:在resources/static/error/ 下定义

        如添加404页面: resources/static/error/404.html页面,中文注意页面编码

    模板引擎页面:在templates/error/ 下定义

        如添加5xx页面: resources/templates/error/5xx.ftl
        注:resources/templates/error/ 的优先级比较 resources/static/error/高

        通过在src/main/resources/templates文件夹中添加error.html错误页面实现自定义错误信息。

        通过在src/main/resources/templates/error中添加404.html等以http错误码开头的页面实现不同http错误状态的不同展现。


/error 请求的触发前提是系统中抛出的异常到最终都没有被处理掉:

    Spring Boot可以通过 @ControllerAdvice 和 @ExceptionHandler 实现捕获系统中的异常。

    如果 @ControllerAdvice 中如果有其他异常没有捕获到,最终仍然会通过 BasicErrorController 处理这些异常。


request 对象中包含的异常信息:
    javax.servlet.error.status_code             类型为Integer        错误状态代码
    javax.servlet.error.exception_type          类型为Class          异常的类型
    javax.servlet.error.message                 类型为String         异常的信息
    javax.servlet.error.exception               类型为Throwable      异常类
    javax.servlet.error.request_uri             类型为String         异常出现的页面
    javax.servlet.error.servlet_name            类型为String         异常出现的servlet名

    Object throwableObject = request.getAttribute("javax.servlet.error.exception");
    if (throwableObject == null) {
        //未发现异常
        return;
    }
    Throwable throwable = (Throwable) throwableObject;
    log.error("捕获一个异常", throwable);


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

    //错误参数
    private final ErrorProperties errorProperties;

    /**
     * ErrorAttributes:
     *      提供给用户可以记录或显示的错误属性。
     *      我们可以自定义一个ErrorAttributes类,只要实现ErrorAttributes即可。
     *      默认 Spring Boot 已经帮我们实现了一个DefaultErrorAttributes。
     */
    public CommonController(ErrorAttributes errorAttributes,
                            ServerProperties serverProperties) {
        super(errorAttributes);
        this.errorProperties = serverProperties.getError();
    }

    /**
     * 错误处理器
     */
    @GetMapping
    public String handleError(HttpServletRequest request, HttpServletResponse response, Model model) {

        //Http状态
        HttpStatus status = getStatus(request);

        log.error("错误Path:[{}],状态码:[{}]", getErrorPath(), status);

        //将错误描述放入error属性中
        Map errorDetail = Collections.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request)));
        model.addAttribute("error", errorDetail);

        log.debug("错误描述:[{}]", errorDetail);

        if (status.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
            //内部服务错误:500
            return "themes/主题名/500";
        } else if (status.equals(HttpStatus.NOT_FOUND)) {
            //未发现错误:404
            return "themes/主题名/404"
        } else {
            //默认错误处理器
            return "common/error/error";
        }
    }

    /**
     * 获取错误Path:/error
     */
    @Override
    public String getErrorPath() {
        return this.errorProperties.getPath();
    }
}

Controller 返回值

1、返回 ModelAndView

    返回 ModelAndView 是最常见的一种返回结果。
    需要在方法结束的时候定义一个 ModelAndView 对象,并对 Model 和 View 分别进行设置。


2、返回String

    1):字符串代表逻辑视图名

        真实的访问路径 = “前缀” + 逻辑视图名 + “后缀”

        Model的返回方式如下:

            public String test(Model model){
                model.addAttribute(attrName,attrValue);
                return "逻辑视图名";
            }

    2):代表redirect重定向(return "redirect:path")

        使用redirect进行重定向那么地址栏中的URL会发生变化,同时不会携带上一次的request。

    3):代表forward转发(return "forward:path")

        通过forward进行转发,地址栏中的URL不会发生改变,同时会将上一次的request携带到下一次请求中去。


3、返回void

    返回这种结果的时候可以在Controller方法的形参中定义HTTPServletRequest和HTTPServletResponse对象进行请求的接收和响应。

    1)使用request转发页面
        request.getRequestDispatcher("转发路径").forward(request,response);

    2)使用response进行页面重定向
        response.sendRedirect("重定向路径");

    3)也可以使用response指定响应结果
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter.write("json串");

你可能感兴趣的:(Halo(十一))