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<String, Object> 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串");
原文地址:https://www.cnblogs.com/loveer/p/11966174.html