利用@ControllerAdvice和@ExceptionHandler自定义全局异常并打印日志到前端页面

@ExceptionHandler

单独使用一般是用在控制器的内部某个方法上,表示捕捉控制器内部抛出的异常

详细的使用方法请参考:lkforce的博客

@ControllerAdvice+@ExceptionHandler

Spring 3.2之后加入了新的@ControllerAdvice注解,可以支持全局的异常处理。

自定义全局异常并打印系统默认日志demo:

第一步:配置文件

设置日志级别和日志保存地址

logging.level.root=info
logging.level.kjl.blog=debug
logging.file.name=log/blog.log

第二步:编写处理异常控制器

@ControllerAdvice控制器增强

@ExceptionHandler(Exception.class)申明捕获异常类

通过新建一个ModelAndView并返回特定的页面,在页面中凸显出想要显示的信息

@ControllerAdvice
public class ControllerExceptionHandler {
 private final Logger logger=LoggerFactory.getLogger(this.getClass());
    @ExceptionHandler(Exception.class)
    public ModelAndView exceptionHandler(HttpServletRequest request,  Exception e) throws Exception {
        logger.error("Request URL : {}, Exception : {}",request.getRequestURL(),e);
        ModelAndView mv=new ModelAndView("error/error");
        mv.addObject("url",request.getRequestURL());
        mv.addObject("exception",e);
        return mv;
    }
}

第三步:编写前端展示页面error.html

此处要引入thymeleaf依赖,和对thymeleaf进行配置

//maven依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
//配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.mode=HTML

在静态资源templates下新建一个error文件夹,在error文件夹下新增error.html页面

                                                                           

       编写error页面

xmlns定义命名空间,其中th:text="${属性}"中属性为前面控制器创建的mv中的键入属性

exception.stackTrace为异常的堆栈信息

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>出错啦</h2>
<ul>
    <li>url:<span th:text="${url}"></span></li>
    <li>e:<span th:text="${exception}"></span></li>
</ul>
<h2>出错信息如下:</h2>
<ul>
    <li th:each="st:${exception.stackTrace}">
            <span th:text="${st}"></span>
    </li>
</ul>
</body>
</html>

编写一个错误指令9/0

    @GetMapping("hello")
    public String hello(){
        int i=9/0;
        return "index";
    }

页面打印异常

                     

第四步:处理业务异常:比如找不到资源和页面等

1.新建异常NotFoundException继承RuntimeException

设置@ResponseStatus工具类解析自定义异常

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
    public NotFoundException() {
        super();
    }

    public NotFoundException(String message) {
        super(message);
    }

    public NotFoundException(String message, Throwable cause) {
        super(message, cause);
    }
}

2.在ControllerExceptionHandler类中exceptionHandler方法中加入以下代码,判断状态是否为空,如果不为空,抛出异常:

        if(AnnotationUtils.findAnnotation(e.getClass(),ResponseStatus.class)!=null){
            throw e;
        }

3.自定义404异常显示信息

通过getErrorAttribute.get("status")来捕获异常状态码,并返回特定的异常信息

//自定义error数据
@Component
public class MyErrorAttribute extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String,Object> getErrorAttributes=super.getErrorAttributes(webRequest,options);
        if((int)getErrorAttributes.get("status")==404){
            getErrorAttributes.put("custommsg","您要找的博客找不到啦");
            getErrorAttributes.put("message","您访问的了一个错误页面");
        }
        return getErrorAttributes;
    }
    @Override
    public Throwable getError(WebRequest webRequest) {
        return super.getError(webRequest);
    }
}

4.编写404页面,输出自定义信息,同样放在templates的error目录下

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<table border="1" bgcolor="#7fffd4">

    <tr>
        <td>custommsg</td>
        <td th:text="${custommsg}"></td>
    </tr>
    <tr>
        <td>timestamp</td>
        <td th:text="${timestamp}"></td>
    </tr>
    <tr>
        <td>status</td>
        <td th:text="${status}"></td>
    </tr>
    <tr>
        <td>error</td>
        <td th:text="${error}"></td>
    </tr>
    <tr>
        <td>message</td>
        <td th:text="${message}"></td>
    </tr>
    <tr>
        <td>path</td>
        <td th:text="${path}"></td>
    </tr>
</table>
</body>
</html>

5.编写测试类

    @GetMapping("none")
    private String none() {
        String blog=null;
        if (blog==null) throw new NotFoundException("none发出的请求导致博客不存在");
        return "index";
    }

6.结果显示

访问none:

                         

访问不存在的类:

                        

水平有限,错误请指正,一起学习,一起进步!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@ControllerAdvice 是一个注解,用于定义全局异常处理器类。我们可以在该类中定义多个 @ExceptionHandler 注解方法来处理不同类型的异常。当系统中出现异常,会根据异常类型找到对应的 @ExceptionHandler 方法进行处理。 具体的步骤如下: 1. 创建一个类,并用 @ControllerAdvice 注解标记。 2. 在该类中定义多个方法,每个方法上使用 @ExceptionHandler 注解,并传入对应的异常类型作为参数。 3. 在方法中编写具体的异常处理逻辑。 例如,我们可以创建一个全局异常处理器类 GlobalExceptionHandler: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception e) { // 处理 Exception 类型的异常 // 返回自定义的错误信息 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal Server Error"); } @ExceptionHandler(RuntimeException.class) public ResponseEntity<String> handleRuntimeException(RuntimeException e) { // 处理 RuntimeException 类型的异常 // 返回自定义的错误信息 return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Bad Request"); } // 可以添加更多的异常处理方法... } ``` 在上述例子中,我们定义了两个异常处理方法,分别处理 Exception 类型和 RuntimeException 类型的异常。当系统中抛出对应的异常,会调用相应的处理方法并返回自定义的错误信息。 这样,在整个系统中任何地方出现的对应类型的异常都会被统一处理,提高了代码的可维护性和错误处理的一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值