博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 自定义注解实现后端防重复提交操作
阅读量:4029 次
发布时间:2019-05-24

本文共 5066 字,大约阅读时间需要 16 分钟。

实现思路:当进入到页面生成token。进行表单提交后。校验token。第一次提交成功消除token信息。多次提交发现token不存在。校验不通过

用的如下类:

GenerateToken注解标识在方法上。自动生成token。返回到页面。由下一次表单提交验证
ValidateToken注解标识在方法上。用来验证提交来的信息是否有token信息。以及验证重复提交
AopRejectMultSubmitConfig类基于aop代理。进行切入点切入。GenerateToken注解再方法进入之前进行生成token。ValidateToken注解进行的是环绕同通知。验证token.如果通过。调用方法

代码如下:

GenerateToken注解

==================GenerateToken=======================

@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface GenerateToken {    String size() default "64";}

===================GenerateToken======================

ValidateToken注解===================ValidateToken======================@Target(ElementType.METHOD)@Documented@Retention(RetentionPolicy.RUNTIME)public @interface ValidateToken {}

===================ValidateToken======================

 

AopRejectMultSubmitConfig 类

/** * author:wwz */@Component@Aspectpublic class AopRejectMultSubmitConfig {    private final static Logger logger = LoggerFactory.getLogger(AopRejectMultSubmitConfig.class);    @Autowired    private RedisTemplate redisTemplate;    private static final String PROJ_ST_MENU = "proj:menu:";    private static final int MAX_AGE = 600;    private static class LockHolder{        private static Lock lock = new ReentrantLock(true);    } ;    /**     * 生成token     */    @Before("@annotation(com.x.modules.gcjsy.basic.annoation.GenerateToken)")    public void before(){        HttpServletResponse response =  ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();        HttpServletRequest request =  ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        if(!isHaveToken(request)){            String uuid = UUID.randomUUID().toString();            initCookie(response,uuid,MAX_AGE);            UserSession userSession = PermissionHelper.currentUserSession();            redisTemplate.opsForValue().set(PROJ_ST_MENU+uuid+":"+request.getRequestURI()+":"+userSession.getUserId(),request.getRequestURI(),MAX_AGE, TimeUnit.SECONDS);        }    }    /**     * 判断是否有token     * @param request     * @return     */    private boolean isHaveToken(HttpServletRequest request){        String value = getValue(request);        if(value == null){            return false;        }        UserSession userSession = PermissionHelper.currentUserSession();        Object url = redisTemplate.opsForValue().get(PROJ_ST_MENU+value+":"+request.getRequestURI()+":"+userSession.getUserId());        if(url == null||"".equals(url)||!request.getRequestURI().equals(url)){            return false;        };        return true;    }    private void initCookie(HttpServletResponse response,String uuid,int maxAge){        Cookie cookie = new Cookie("tokenUUID",uuid);        cookie.setPath("/");        cookie.setMaxAge(maxAge);        cookie.setHttpOnly(true);        response.addCookie(cookie);    }    private String getValue(HttpServletRequest request){        Cookie[] cookies = request.getCookies();        for(Cookie cookie:cookies) {            if ("tokenUUID".equals(cookie.getName())) {                return cookie.getValue();            }        }        return null;    }    /**     * 校验token     */    @Around("@annotation(com.x.modules.gcjsy.basic.annoation.ValidateToken)")    public Object  methodBefore(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {        HttpServletRequest request =  ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        HttpServletResponse response =  ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();        String uuid =  getValue(request);        if(uuid == null){            throw new Exception("请刷新重试!");        }        UserSession userSession = PermissionHelper.currentUserSession();        String userId = userSession.getUserId();        String referer = request.getHeader("referer");        if(referer!=null){            referer = referer.substring(referer.indexOf("/c"));        }        String key  = PROJ_ST_MENU+uuid+":"+referer+":"+userId;        Object value = redisTemplate.opsForValue().get(key);        if(value!=null&&value.equals(referer)){            try{                //此除加锁。如果是分布式系统。更改成分布式锁                if(LockHolder.lock.tryLock(10,TimeUnit.SECONDS)){                    redisTemplate.expire(key,0,TimeUnit.SECONDS);                    initCookie(response,"",0);                    return proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());                }            }catch (Exception e){                e.printStackTrace();                /**                 * 异常回滚                 */                initCookie(response,uuid,MAX_AGE);                redisTemplate.opsForValue().set(key,referer,MAX_AGE, TimeUnit.SECONDS);                throw new Exception("操作异常");            }finally {                LockHolder.lock.unlock();            }        }        logger.error("请不要重复操作");        return null;    }}如何使用?

跳转到表单页面增加@GenerateToken注解如下:此页面会自动生成tokenUUID。

进行表单提交方法上增加@ValidateToken注解如下:会进行验证token信息

验证通过。调用方法。验证失败,进行错误提示:

转载地址:http://amvbi.baihongyu.com/

你可能感兴趣的文章
浅谈 Facade 模式
查看>>
单例模式中,懒汉式和饿汉式的区别
查看>>
设计模式之Factory
查看>>
使用Hibernate进行大数据量的性能测试
查看>>
浅谈HTTP的无状态性
查看>>
web service中的事务控制
查看>>
程序调用飞信API发送免费短信(JAVA例子,其他语言一样用)
查看>>
向指定URL发送GET方法的请求(java)
查看>>
Oracle select in/exists/not in/not exits
查看>>
浅谈在Hibernate中使用Oracle sequence
查看>>
hibernate------hql总结
查看>>
Spring框架下PropertyPlaceholderConfigurer类
查看>>
Spring的lobhandler
查看>>
struts 标签logic:iterate用法详解
查看>>
Spring+Hibernate中的(FlushMode.NEVER)错误产生及解决
查看>>
spring的BeanUtils.copyProperties用法
查看>>
JAVA读取Oracle中的blob图片字段并显示
查看>>
Spring JTA应用之JOTM配置
查看>>
spring JdbcTemplate 的若干问题
查看>>
Servlet和JSP的线程安全问题
查看>>