zoukankan      html  css  js  c++  java
  • SpringBoot基于切面来拦截@PathVariable参数及抛出异常全局处理方法

    SpringBoot基于切面来拦截@PathVariable参数及抛出异常全局处理方法

    微信小程序的接口验证防止非法请求,登录的时候获取openId生成一个七天有效期token存入redis中。

    后续每次请求都需要把token作为参数传给后台接口进行验证,为了方便使用@PathVariable 直接将参数做为路径传过来 不用每一次都添加param参数也方便前端接口的请求。

    例如:

    @ApiOperation(value = "小程序登录")
    @PostMapping("/login")
    public AntdResponse login(@RequestParam String username, @RequestParam String password, @RequestParam String openId) throws Exception {
        String st = wxTokenService.passport(username, password);
        //省略。。。。。
        String wxToken = IdUtil.simpleUUID();
        data.put("wxToken", wxToken);
        wxTokenService.saveWxTokenToRedis(wxToken, openId);
        return new AntdResponse().success("登录成功,登录有效期七天").data(data);
    }
    
    @ApiOperation(value = "预约订单")
    @PostMapping("/{wxToken}/addOrder")
    public AntdResponse addOrder(@PathVariable String wxToken, @RequestBody ProductOrderDto productOrderDto){
        String openId = wxTokenService.getOpenIdByWxToken(wxToken);
        orderService.addOrder(openId, productOrderDto);
        return new AntdResponse().success("预约订单成功");
    }
    

    为了方便统一验证,基于切面来实现数据的验证。

    package cn.pconline.antd.smallshop.interceptor;
    
    import cn.pconline.antd.common.exception.WxTokenException;
    import cn.pconline.antd.smallshop.service.IWxTokenService;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import org.springframework.web.servlet.HandlerMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.Map;
    
    /**
     * @Description 微信小程序登录拦截
     * @Author jie.zhao
     * @Date 2020/10/26 18:08
     */
    @Component
    @Aspect
    public class WxMiniInterceptor {
    
        @Autowired
        private IWxTokenService wxTokenService;
        
        //这里需要把登录的请求控制器排除出去
        @Pointcut("within (cn.pconline.antd.smallshop.wxmini..*) && !within(cn.pconline.antd.smallshop.wxmini.WxMiniLoginController)")
        public void pointCut() {
        }
    
        @Around("pointCut()")
        public Object trackInfo(ProceedingJoinPoint joinPoint) throws Throwable {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            Map pathVariables = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            String wxToken = (String) pathVariables.get("wxToken");
            if (wxToken == null) {
                throw new WxTokenException("微信小程序令牌参数缺失!");
            }
            String openId = wxTokenService.getOpenIdByWxToken(wxToken);
            if (openId == null || "".equals(openId)) {
                throw new WxTokenException("登录失效,请重新登录!");
            }
            return joinPoint.proceed();
        }
    }
    

    全局异常处理

    @RestControllerAdvice
    @Order(value = Ordered.HIGHEST_PRECEDENCE)
    public class GlobalExceptionHandler {
        @ExceptionHandler(value = WxTokenException.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public AntdResponse handleWxTokenException(WxTokenException e) {
            log.error("微信Token拦截异常信息:", e);
            return new AntdResponse().message(e.getMessage()).code(Code.C500.getCode().toString()).status(ResponseStat.ERROR.getText());
        }
    }
    
    package cn.pconline.antd.common.exception;
    
    /**
     * 微信授权token异常
     */
    public class WxTokenException extends RuntimeException  {
    
        private static final long serialVersionUID = -3608667856397125671L;
    
        public WxTokenException(String message) {
            super(message);
        }
    }
    

    这里需要注意的是 WxTokenException 要继承RuntimeException而不是Exception,否则的话会报UndeclaredThrowableException。

    java.lang.reflect.UndeclaredThrowableException
        at com.insigmaunited.lightai.controller.UserController$$EnhancerBySpringCGLIB$$e4eb8ece.profile(<generated>)
    

    异常原因:
    我们的异常处理类,实际是 动态代理的一个实现。
    如果一个异常是检查型异常并且没有在动态代理的接口处声明,那么它将会被包装成UndeclaredThrowableException.
    而我们定义的自定义异常,被定义成了检查型异常,导致被包装成了UndeclaredThrowableException
    java.lang.reflect.UndeclaredThrowableException的解决

  • 相关阅读:
    自定义Toast
    kafka概念扫盲
    ZooKeeper面试题
    写给程序员儿子的一封信
    hashCode() 和 equals()的问题解答及重写示范
    git下载安装、配置及idea初始化
    配置 git公钥报错:unknown key type -rsa
    Java中的各种锁
    Kafka 基本原理
    MySQL 索引总结
  • 原文地址:https://www.cnblogs.com/cnsyear/p/13915122.html
Copyright © 2011-2022 走看看