当系统发生异常时,自动跳转到我们自己定义的异常页面(404,500等)。完整测试demo
后端:spring boot
前端:Thymeleaf(简单使用)
一、使用spring boot默认的命名规则
1.完整项目结构:
2.注意要点:
- spring boot 建议自定义页面放在resources -> templates下。
- 命名规范,发生错误异常,spring boot 会自动到resources -> templates -> error下找对应的错误码文件,如,404、500等,建议命名符合此规范。
3.简单编码:
404.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>404</h1>
</body>
</html>
500.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>500</title>
</head>
<body>
<h1>500</h1>
</body>
</html>
首页index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
</body>
</html>
IndexController.java:
package com.beishanyao.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
@GetMapping("/")
public String index(){
//以下一行系统会抛出异常,因为不能除以0
int i = 10/0;
return "index";
}
}
4.运行测试
在浏览器中输入:http://127.0.0.1:8081/ 显示如下表明500错误已被我们拦截。
故意输错地址为:http://127.0.0.1:8081/a 显示如下表明404错误被我们拦截。
二、跳转到自定义的文件名(error.html),在以上代码上稍作补充。
1.完整项目结构
2.代码:
error.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>错误</title>
</head>
<body>
<h1>错误</h1>
</body>
</html>
ControllerExceptionHandler.java:
package com.beishanyao.hander;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
* ControllerAdvice: 会拦截有【@Controller】标注的类
* @author beishanyao
*/
@ControllerAdvice
@Slf4j
public class ControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHandler(HttpServletRequest request,Exception e){
log.error("Request URL : {}, Exception : {}",request.getRequestURL(),e);
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception",e);
//返回到 templates 下的 error/error 页面
mv.setViewName("error/error");
return mv;
}
}
注意注解 @Slf4j 为 Lombok 处理日志的注解,Lombok可以大大提高开发效率且简单好用,可以了解下。
3.启动项目并运行
在浏览器中输入:http://127.0.0.1:8081/ 显示如下表示拦截成功
同时,服务端会报如下错误:
我们可以把前端代码稍作修改,让错误显示到前端页面,这样的好处是报错之后不用跑到服务器上看错误日志了:
error.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>错误</title>
</head>
<body>
<h1>错误</h1>
<div>
<div th:utext="'<!--'" th:remove="tag"></div>
<div th:utext="'Failed Request URL : ' + ${url}" th:remove="tag">
</div>
<div th:utext="'Exception message : ' + ${exception.message}"
th:remove="tag"></div>
<ul th:remove="tag">
<li th:each="st : ${exception.stackTrace}" th:remove="tag"><span
th:utext="${st}" th:remove="tag"></span></li>
</ul>
<div th:utext="'-->'" th:remove="tag"></div>
</div>
</body>
</html>
4.重新编译运行
访问:http://127.0.0.1:8080/ 显示如下
右键,查看源代码,发现错误日志打印出来了:
三、自定义异常类
1.完整项目结构:
三、自定义异常类
1.完整项目结构:
2.代码:
NotFoundException.java:
package com.beishanyao;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
public NotFoundException() {
}
public NotFoundException(String message) {
super(message);
}
public NotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
ControllerExceptionHandler.java:
package com.beishanyao.hander;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
* ControllerAdvice: 会拦截有【@Controller】标注的类
* @author beishanyao
* @date 2020/1/10
*/
@ControllerAdvice
@Slf4j
public class ControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHandler(HttpServletRequest request,Exception e) throws Exception {
log.error("Request URL : {}, Exception : {}",request.getRequestURL(),e);
/**
* if模块
* 标注了 ResponseStatus 状态的异常,不在此处统一处理,直接抛出异常,让 springboot 本身处理
*/
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
throw e;
}
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception",e);
//返回到 templates 下的 error/error 页面
mv.setViewName("error/error");
return mv;
}
}
3.启动项目并运行
在浏览器中输入:http://127.0.0.1:8081/ 显示如下表示拦截成功