首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >全局异常处理

全局异常处理

作者头像
用户11288958
发布2025-08-01 08:11:51
发布2025-08-01 08:11:51
13600
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行

 三十七、全局异常处理

思考一下,前面写的代码还有啥问题: 就是我们没有考虑异常出现的时候 例如:

发现代码中有 int a = 100 / 0; 项目依然可以跑起来,但是实际上我们都知道,代码执行到这里可以是会报错的。 那么如果这个错误不明显,不像int a = 100 / 0; 那么我们要找到这个错误是一件很困难的事情 注意:判断密码错误等不属于异常,这只是逻辑错误的判断 

如果都加try catch会让代码变得很丑陋,因此我们要使用全局异常处理

异常:

  • 编译时异常
  • 运行时异常 

在oj-common下,创建oj-common-security子工程

创建GlobalExceptionHandler类

@RestControllerAdvice注解 当抛出异常时,@RestControllerAdvice 标注的类将被自动调用,并根据异常类型和处理程序的注解来决定如何处理该异常。这使得开发者可以在整个应用程序范围内统一处理异常。 @ExceptionHandler注解 @ExceptionHandler一般与@RestControllerAdvice配合使用,使用其来捕获和处理不同类型的异常。 注意: 1.我们尽量将抛出的异常都使用自定义异常,这样便于在异常处理处进行异常处理,比如统一返回json格式,或者统一进行日志记录等。 2.对于其他微服务来讲,它也是外部bean,因此要加上这个文件,才能将这个bean交给Spring容器去管理 3.为了让用户不看到我们的后台具体出什么问题了,因此就返回一个服务器异常就行了,而我们程序员就看日志的错误就行了

代码语言:javascript
代码运行次数:0
运行
复制
package com.qyy.common.security.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.qyy.common.core.domain.R;
import com.qyy.common.core.enums.ResultCode;
import com.qyy.common.security.exception.ServiceException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Collection;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 全局异常处理器
 */
@RestControllerAdvice//全局异常处理器
@Slf4j
//我们尽量将抛出的异常都使用自定义异常,这样便于在异常处理处进行异常处理,比如统一返回json格式,或者统一进行日志记录等。
public class GlobalExceptionHandler {
    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public R<?> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                    HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return R.fail(ResultCode.ERROR);
    }

    //拦截业务异常
    @ExceptionHandler(ServiceException.class)
    public R<?> handleServiceException(ServiceException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        ResultCode resultCode = e.getResultCode();
        log.error("请求地址'{}',发生业务异常: {}", requestURI, resultCode.getMsg(), e);
        return R.fail(resultCode);
    }

    //拦截参数校验异常
    @ExceptionHandler(BindException.class)
    public R<Void> handleBindException(BindException e) {
        log.error(e.getMessage());
        String message = join(e.getAllErrors(),
                DefaultMessageSourceResolvable::getDefaultMessage, ", ");
        return R.fail(ResultCode.FAILED_PARAMS_VALIDATE.getCode(), message);
    }

    //拦截验证异常
    private <E> String join(Collection<E> collection, Function<E, String>
            function, CharSequence delimiter) {
        if (CollUtil.isEmpty(collection)) {
            return StrUtil.EMPTY;
        }
        return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
    }

    /**
     * 拦截运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public R<?> handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生运行时异常.", requestURI, e);
        return R.fail(ResultCode.ERROR);
    }

    /**
     * 系统异常(兜底)
     */
    @ExceptionHandler(Exception.class)
    public R<?> handleException(Exception e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生异常.", requestURI, e);
        return R.fail(ResultCode.ERROR);
    }
}

BindException(处理参数校验失败的异常(如表单数据验证),将错误信息拼接后返回给前端。)

代码语言:javascript
代码运行次数:0
运行
复制
    @ExceptionHandler(BindException.class)
    public R<Void> handleBindException(BindException e) {
        log.error(e.getMessage());
        String message = join(e.getAllErrors(),
                DefaultMessageSourceResolvable::getDefaultMessage, ", ");
        return R.fail(ResultCode.FAILED_PARAMS_VALIDATE.getCode(), message);
    }

异常想不想让用户知道? 

 有些异常不想直接让用户知道,但是有一些异常,有些错误是想让用户知道的。比如新增管理员用户这个接口而言,你传了用户名为空的。那么想让你知道错误原因。

因此我们还要看一下这个异常想不想让用户知道。如果不想就返回:服务器繁忙请稍后重试。

出现空指针异常的话,我们肯定不想让用户知道。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •  三十七、全局异常处理
    • 在oj-common下,创建oj-common-security子工程
      • 创建GlobalExceptionHandler类
    • BindException(处理参数校验失败的异常(如表单数据验证),将错误信息拼接后返回给前端。)
  • 异常想不想让用户知道? 
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档