什么是接口的幂等性,如何实现接口幂等性?( 二 )

3.3 编写创建Token和验证Token的接口以及实现类@Servicepublic interface TokenService {    public Response createToken();    public Response checkToken(HttpServletRequest request);}具体实现类,核心的业务逻辑都写在注释中了
@Servicepublic class TokenServiceImpl implements TokenService {    @Autowired    private RedisTemplate redisTemplate;    @Override    public Response createToken() {        //生成uuid当作token        String token = UUID.randomUUID().toString().replaceAll("-","");        //将生成的token存入redis中        redisTemplate.opsForValue().set(token,token);        //返回正确的结果信息        Response response=new Response(0,token.toString(),null);        return response;    }    @Override    public Response checkToken(HttpServletRequest request) {        //从请求头中获取token        String token=request.getHeader("token");        if (StringUtils.isBlank(token)){            //如果请求头token为空就从参数中获取            token=request.getParameter("token");            //如果都为空抛出参数异常的错误            if (StringUtils.isBlank(token)){                throw new ServiceException(ResponseCode.ILLEGAL_ARGUMENT.getCode().toString(),ResponseCode.ILLEGAL_ARGUMENT.getMsg());            }        }        //如果redis中不包含该token,说明token已经被删除了,抛出请求重复异常        if (!redisTemplate.hasKey(token)){            throw new ServiceException(ResponseCode.REPETITIVE_OPERATION.getCode().toString(),ResponseCode.REPETITIVE_OPERATION.getMsg());        }        //删除token        Boolean del=redisTemplate.delete(token);        //如果删除不成功(已经被其他请求删除),抛出请求重复异常        if (!del){            throw new ServiceException(ResponseCode.REPETITIVE_OPERATION.getCode().toString(),ResponseCode.REPETITIVE_OPERATION.getMsg());        }        return new Response(0,"校验成功",null);    }}3.4 配置自定义注解这是比较重要的一步,通过自定义注解在需要实现接口幂等性的方法上添加此注解,实现token验证
@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface ApiIdempotent {}接口拦截器
public class ApiIdempotentInterceptor implements HandlerInterceptor {    @Autowired    private TokenService tokenService;    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        if (!(handler instanceof HandlerMethod)) {            return true;        }        HandlerMethod handlerMethod= (HandlerMethod) handler;        Method method=handlerMethod.getMethod();        ApiIdempotent methodAnnotation=method.getAnnotation(ApiIdempotent.class);        if (methodAnnotation != null){            // 校验通过放行,校验不通过全局异常捕获后输出返回结果            tokenService.checkToken(request);        }        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {    }}


推荐阅读