错误&异常处理机制

2)错误页指派

image.png
错误页?形如:https://taobao.com/400.html
image.png
未设定错误页时,SpringBoot会提供一个默认的空白页(用浏览器访问)
image.png
用postman访问时,返回json字符串,同样包含以上数据
image.png
返回不同的结果,区别在于http请求头中的Accept属性的值
1571730668728.png1571730690322.png

定义错误页
查看文档 [第四章] - [第29.1小节] - [Custom Error Pages]

方式1:
创建/public/error/404.html页面,注意只支持静态页面
image.png

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>404</title>
  6. </head>
  7. <body>
  8. 方式一<br>
  9. 这里是/public/error/404.html<br>
  10. 现在找不到页面了
  11. </body>
  12. </html>

image.png

方式2:
创建/templates/error/404.html页面,支持动态页面,并且优先级比/public/error目录高。
注意: 可以通过4xx.html页面,代表所有以4开头的错误码要查找的页面(400,401,402…),5xx.html同理。 当404.html和4xx.html同时存在,优先显示精确的错误码页面,即为404.html
image.png

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>4xx</title>
  6. </head>
  7. <body>
  8. 方式二<br>
  9. 这里是/templates/error/4xx.html<br>
  10. <p th:text="${timestamp}">timestamp</p>
  11. <p th:text="${status}">status</p>
  12. <p th:text="${message}">message</p>
  13. 现在找不到页面了
  14. </body>
  15. </html>

image.png

方式3:(优先级高于方式二)
创建自定义的错误视图解析器,实现ErrorViewResolver接口
image.png

package com.duing.resolver;

import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 声明组件,需要是一个bean,才能被spring容器处理,才会生效
 */
@Component
public class MyErrorViewResolver implements ErrorViewResolver {
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        if(status.equals(HttpStatus.NOT_FOUND)){
            ModelAndView modelAndView=new ModelAndView();
            modelAndView.setViewName("/resolver404");
            return modelAndView;
        }
        return null;
    }
}

image.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>4xx</title>
</head>
<body>
方式三<br>
这里是/templates/resolver404.html<br>
现在找不到页面了
</body>
</html>

image.png
方式4:(优先级高于方式三)
使用WebServerFactoryCustomizer来注册bean,通过更改错误码的处理路径,来指定不同的页面。
image.png

package com.duing.customizer;

import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

@Configuration
public class MyCustomizer {

    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> customizer(){
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                ErrorPage errorPage=new ErrorPage(HttpStatus.NOT_FOUND,"/error404");
                factory.addErrorPages(errorPage);
            }
        };
    }

}
package com.duing.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MyErrorController {

    @RequestMapping("/error404")
    public String error404(){
        return "error-404";
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>4xx</title>
</head>
<body>
方式四<br>
这里是/templates/error-404.html<br>
现在找不到页面了
</body>
</html>

image.png

3) 全局异常处理

通过@ControllerAdvice注解监听controller中出现的所有异常,然后执行@ExceptionHandler注解对应的具体方法,跳转到错误页

package com.duing.handler;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

/**
 * @ControllerAdvice标识的类
 * controller处理时发生异常都会被这个类接收
 * 
 * 切面的处理方式  使用@ControllerAdvice注解(spring3.x提供的)
 */
@ControllerAdvice
public class MyExceptionHandler {

    //具体处理哪种异常
    @ExceptionHandler(Exception.class)
    public ModelAndView handler(Exception e){
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.setViewName("/error");//错误页
        modelAndView.addObject("message",e.getMessage());
        return modelAndView;
    }
}
@RequestMapping("/myerror")
    public String error() throws Exception{
        throw new Exception("测试异常");
    }
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>4xx</title>
</head>
<body>
这里是/templates/error.html<br>
出现异常<br>
<p th:text="${message}">message</p>
</body>
</html>

image.png

日志

1996 log4j = log for java (apache收购) 成为了日志标准
2002 jul = java util logging —-sun公司
jcl = jakarta commons logging 日志接口——apache公司
2006 logback = log4j 升级版 slf4j = simple logging facade for java 日志门面接口
2012 log4j 2 apache
Commons logging || slf4j(主流 +logback)
image.png
日志内容举例
2022-01-14 16:26:58.609 INFO 16600 --- [ main] com.duing.LoggingApplication : Started LoggingApplication in 1.486 seconds (JVM running for 2.234)

通用日志格式:
时间日期+日志级别+进程ID+分隔符(正式开始)+线程名+Logger名(类名)+日志内容
日志级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL
日志地址:默认输出到控制台

日志文件输出
方式一:在application.properties中配置logging.file.path(2.2版本之后才是这个)

logging.file.path = D:/JavaProject/SpringBoot/log

生成默认日志文件spring.log
image.png
方式二:在application.properties中配置logging.file.name(2.2版本之后才是这个)

logging.file.name =  log.log

image.png
如果两者同时出现,则只有logging.file.name生效

日志级别控制
image.png
image.png
logback.xml
image.png
image.png
image.png