牛客网后端项目实战(二十三):统一处理异常

本文介绍SpringBoot中使用@ControllerAdvice和@ExceptionHandler实现全局异常处理的方法,包括自定义错误页面及异常处理逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


SpringBoot处理异常的5种方式

  • @ControllerAdvice
    • 用于修饰类,表示该类是Controller的全局配置类。
    • 在此类中,可以对Controller进行如下三种全局配置: 异常处理方案、绑定数据方案、绑定参数方案。
  • @ExceptionHandler
    • 用于修饰方法,该方法会在Controller出现异常后被调用,用于处理捕获到的异常。
  • @ModelAttribute
    • 用于修饰方法,该方法会在Controller方法执行前被调用,用于为Model对象绑定参数。
  • @DataBinder
    • 用于修饰方法,该方法会在Controller方法执行前被调用,用于绑定参数的转换器。

一、自定义错误页面

1.1 SpringBoot 默认的处理异常的机制:

SpringBoot 默认的已经提供了一套处理异常的机制。一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个叫 BasicExceptionController 来处理/error 请求,然后跳转到默认显示异常的页面来展示异常信息

1.2 如 果 我 们需要将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , (需要在src/main/resources/templates 目录下创建error.html页面。注意:名称必须叫 error ??)

在这里插入图片描述

然后再处理模板:
1、声明 thymeleaf 模板
2、修改静态资源/相对路径
3、复用首页等头部信息

注解处理异常

由spring提供的全局配置类,本次只用到ExceptionHandler注解。在controller包下新建advice包,新建ExceptionAdvice。

新建通知类

package com.nowcoder.community.controller.advice;

import com.nowcoder.community.util.CommunityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@ControllerAdvice(annotations = Controller.class)
public class ExceptionAdvice {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    @ExceptionHandler({Exception.class})
    public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException { 
    	// 记录日志   
        logger.error("服务器发生异常: " + e.getMessage());  // 异常概括
        for (StackTraceElement element : e.getStackTrace()) {  // 遍历栈
            logger.error(element.toString());
        }

		//  根据是否是异步请求,返回给浏览器不同的结果
		//  请求中获取请求头参数x-requested-with
        String xRequestedWith = request.getHeader("x-requested-with");
        if ("XMLHttpRequest".equals(xRequestedWith)) {              // 说明是异步请求,浏览器希望得到json对象
        	// 向浏览器返回普通字符串,然后人为的转换为json对象
            response.setContentType("application/plain;charset=utf-8"); //声明字符集,支持中文
            PrintWriter writer = response.getWriter();  // 获取输出流
            writer.write(CommunityUtil.getJSONString(1, "服务器异常!")); // 输出json字符串
        } else {
        	// 否则,不是异步请求,重定向到error界面
            response.sendRedirect(request.getContextPath() + "/error");
        }
    }

}

代码逻辑:
1、@ControllerAdvice(annotations = Controller.class):注解只扫描带有controller注解的那些Bean,这些Bean被统一处理
2、@ExceptionHandler({Exception.class}):表示该方法会处理捕捉到的所有异常(因为 Exception 是所有异常的父类)

好处:不需要对任何一个controller进行处理,就可以捕获异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值