springboot全局异常捕获

异常捕获

异常处理逻辑集中管理,易于维护和扩展,这边我的项目是用于jwt验证token时使用

  • 项目结构

自定义异常类

  • 用来表示jwt验证失败的情况,包含一个状态码和消息,这样就可以在捕获异常时使用这些信息

    package com.example.englishhub.exception;
    
    /**
     * @Author: hahaha
     * @Date: 2024/4/11 14:09
     */
    
    public class JwtValidationException extends RuntimeException {
        private final String statusCode;
    
        public JwtValidationException(String statusCode, String message) {
            super(message);
            this.statusCode = statusCode;
        }
    
        public String getStatusCode() {
            return statusCode;
        }
    }
    

全局异常处理器

  • 添加对 JwtValidationException的处理逻辑,使用 @ControllerAdvice注解

    package com.example.englishhub.config;
    
    import com.example.englishhub.exception.JwtValidationException;
    import com.example.englishhub.utils.Result;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    
    /**
     * @Author: hahaha
     * @Date: 2024/4/11 14:10
     */
    
    // 全局异常处理
    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(JwtValidationException.class)
        public ResponseEntity<Result<String>> handleJwtValidationException(JwtValidationException ex) {
            Result<String> result = new Result<>();
            result.setStatusCode(ex.getStatusCode());
            result.setMessage(ex.getMessage());
            return new ResponseEntity<>(result, HttpStatus.valueOf(Integer.parseInt(ex.getStatusCode())));
        }
    }
    

添加拦截器

public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object o) {
        System.out.println("进入拦截器");

        if ("OPTIONS".equals(req.getMethod())) {
            return true;
        }
//        resp.setCharacterEncoding("utf-8");
//        String token = req.getHeader("token");
        String token = req.getHeader("token");
        // JwtUtil.validateToken 方法内部会抛出自定义的 JwtValidationException 异常
        String id = JwtUtil.validateToken(token);
        // 认证成功
        resp.setContentType("application/json; charset=utf-8");
        System.out.println("认证成功:用户 " + id + " 访问资源");
        return true;
    }
}

跨域配置

// 跨域配置
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET","HEAD","POST","PUT","DELETE","OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }

    @Override
    public void addInterceptors(InterceptorRegistry reg) {
        reg.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns(excludePattern());
    }

    public List<String> excludePattern(){
        List<String> ret = new ArrayList<String>();
        ret.add("/user/**");
        ret.add("/swagger-ui.html#/**");
        ret.add("/**");
//        , \"/webjars/**\", \"/v2/**\", \"/swagger-ui.html/**"
        return ret;
    }
}

修改jwt工具类中的逻辑

  • 使其在验证失败时抛出上面定义的 JwtValidationException异常。

    /**
         * 校验jwtToken
         *
         * @param token
         * @return
         */
        // 优化验证逻辑
        public static String validateToken(String token) {
    
            // 使用自定义异常
            if (StringUtils.isBlank(token)) {
                throw new JwtValidationException(ResultType.UNAUTHORIZED.getCode(), "Token为空");
            }
            try {
                Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
                return claims.get(USER_ID, String.class);
            } catch (ExpiredJwtException e) {
                throw new JwtValidationException(ResultType.AGAIN_LOGIN.getCode(), "Token已过期,请重新登录");
            } catch (JwtException e) {
                throw new JwtValidationException(ResultType.UNAUTHORIZED.getCode(), "无效的Token");
            }
        }
    

测试

  • controller层编写验证token函数

         /**
         * 验证Token
         */
        @Operation(summary = "验证Token")
        @GetMapping("/validate")
        public Result validate() {
            Result result = new Result();
            String token = request.getHeader("token");
            System.out.println("token" + token);
            JwtUtil.validateToken(token);
            result.success("Token有效");
            return result;
        }
    
  • postman发请求测试

后续也可以自定义其他异常类,在controller层其他方法抛出即可。
result.success(“Token有效”);
return result;
}

- postman发请求测试

[外链图片转存中...(img-jzNoq2Ac-1713494114064)]

后续也可以自定义其他异常类,在controller层其他方法抛出即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

...Yolo...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值