错误&异常处理机制
2)错误页指派
错误页?形如:https://taobao.com/400.html
未设定错误页时,SpringBoot会提供一个默认的空白页(用浏览器访问)
用postman访问时,返回json字符串,同样包含以上数据
返回不同的结果,区别在于http请求头中的Accept属性的值
定义错误页
查看文档 [第四章] - [第29.1小节] - [Custom Error Pages]
方式1:
创建/public/error/404.html页面,注意只支持静态页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
方式一<br>
这里是/public/error/404.html<br>
现在找不到页面了
</body>
</html>
方式2:
创建/templates/error/404.html页面,支持动态页面,并且优先级比/public/error目录高。
注意: 可以通过4xx.html页面,代表所有以4开头的错误码要查找的页面(400,401,402…),5xx.html同理。 当404.html和4xx.html同时存在,优先显示精确的错误码页面,即为404.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>4xx</title>
</head>
<body>
方式二<br>
这里是/templates/error/4xx.html<br>
<p th:text="${timestamp}">timestamp</p>
<p th:text="${status}">status</p>
<p th:text="${message}">message</p>
现在找不到页面了
</body>
</html>
方式3:(优先级高于方式二)
创建自定义的错误视图解析器,实现ErrorViewResolver接口
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;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>4xx</title>
</head>
<body>
方式三<br>
这里是/templates/resolver404.html<br>
现在找不到页面了
</body>
</html>
方式4:(优先级高于方式三)
使用WebServerFactoryCustomizer来注册bean,通过更改错误码的处理路径,来指定不同的页面。
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>
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>
日志
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)
日志内容举例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
方式二:在application.properties中配置logging.file.name(2.2版本之后才是这个)
logging.file.name = log.log
如果两者同时出现,则只有logging.file.name生效
日志级别控制
logback.xml