spring Aop实现身份验证和springboot异常统一处理

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> spring Aop实现身份验证和springboot异常统一处理

文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号: 好好学java,获取优质学习资源。

一、spring Aop身份验证

一般,如果用户没有登录的话,用户只可以查看商品,但是其他的,比如支付等是不能够进行操作的,这个时候,我们就需要用到用户拦截, 或者说身份验证了。

首先定义一个类 AuthorizeAspect,以 @Aspect注解。

然后把所有以 Controller声明为切点,但排除 UserController,因为这个Controller就是验证用户登录的Controller。


  @Pointcut("execution(public * com.sihai.controller *.*(..))"+
    "&& !execution(public * com.sihai.controller.UserController.*(..))")
    public void verify(){}

最后对这个切点做一些前置处理,因为用户登录后,按照我们之前写的逻辑,cookie和redis中应该含有用户的信息,所以现在查询这两个地方,来验证用户有没有登录。


   @Before("verify()")
    public void doVerify(){
        ServletRequestAttributes attributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request=attributes.getRequest();

        //查询cookie
        Cookie cookie= CookieUtil.get(request,CookieConstant.TOKEN);
        if (cookie==null){
            log.warn("Cookie中查不到token");
            throw new   AuthorizeException();
        }

        //去redis查询,这个下面的redis用到的是springboot的redis工具类
        String tokenValue=redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX,cookie.getValue()));
        if (StringUtils.isEmpty(tokenValue)){
            log.warn("Redis中查不到token");
            throw new   AuthorizeException();
        }
    }

完整代码如下:


@Aspect
@Component
@Slf4j
public class AuthorizeAspect {<!-- -->

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Pointcut("execution(public * com.sihai.controller.  *.*(..))"+
    "&amp;&amp; !execution(public * com.sihai.controller.  UserController.*(..))")
    public void verify(){}

    @Before("verify()")
    public void doVerify(){
        ServletRequestAttributes attributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request=attributes.getRequest();

        //查询cookie
        Cookie cookie= CookieUtil.get(request,CookieConstant.TOKEN);
        if (cookie==null){
            log.warn(" Cookie中查不到token");
            throw new   AuthorizeException();
        }

        //去redis查询
        String tokenValue=redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX,cookie.getValue()));
        if (StringUtils.isEmpty(tokenValue)){
            log.warn("  Redis中查不到token");
            throw new   AuthorizeException();
        }
    }

}

二、springboot统一异常处理

  • 自定义异常类
    从以上代码中可以看到,如果用户没有登陆,就会抛出一个 AuthorizeException的异常,这是一个自定义的异常。这个异常很简单,只有一个简单的定义,为运行时异常

public class AuthorizeException extends RuntimeException {<!-- -->}

之后我们需要定义一个对这个异常的处理器 ExceptionHandler,当扑获到这个异常,说明用户没有登陆,那就重新调到登陆界面(访问处理登陆的Controller)。

  • 创建全局异常处理类:通过使用 @ControllerAdvice定义统一的异常处理类,而不是在每个Controller中逐个定义。 @ExceptionHandler用来定义函数针对的异常类型,最后将Exception对象和请求URL映射到 error.html
    ```
    @ControllerAdvice
    public class ExceptionHandler {

    @Autowired
    private ProjectUrlConfig projectUrlConfig;

    //拦截登录异常
    @ExceptionHandler(value = AuthorizeException.class)
    public ModelAndView handlerAuthorizeException(){
    ModelAndView mav = new ModelAndView();
    mav.addObject(“exception”, e);
    mav.addObject(“url”, req.getRequestURL());
    mav.setViewName(DEFAULT_ERROR_VIEW);
    return mav;
    }

}


- **实现error.html页面展示**:在templates目录下创建error.html,将请求的URL和Exception对象的message输出。

<!DOCTYPE html>
<html>
<head lang=”en”>
<meta charset=”UTF-8” />
<title>统一异常处理</title>
</head>
<body>
<h1>Error Handler</h1>
<div th:text=”${url}”></div>
<div th:text=”${exception.message}”></div>
</body>
</html>

```

启动该应用,访问:,可以看到如下错误提示页面。

原文地址:https://sihai.blog.csdn.net/article/details/80924870

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> spring Aop实现身份验证和springboot异常统一处理


 上一篇
微信支付和支付宝支付到springmvc+spring+mybatis环境全过程(支付宝和微信支付)... 微信支付和支付宝支付到springmvc+spring+mybatis环境全过程(支付宝和微信支付)...
点击上方“好好学java”,选择“置顶公众号” 优秀学习资源、干货第一时间送达! 好好学java java知识分享/学习资源免费分享 关注  精彩内容  源代码https://github.com/OU
2021-04-04
下一篇 
微信公众号支付开发全过程(java版) 微信公众号支付开发全过程(java版)
文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号: 好好学java,获取优质学习资源。 一、微信官方文档微信支付开发流程(公众号支付)首先我们到微信支付的官方文档的部分查看一下需要的设置。 因为微信支付需要
2021-04-04