spring MVC 后台token防重复提交解决方案
2018-06-18 02:54:32来源:未知 阅读 ()
看到公司有个部门提出了这个问题,补个粗略的解决方案。。。
1.编写拦截器
/** * Description: 防止重复提交 * * @Author liam * @Create Date: 2018/3/9 9:22 */ public class AvoidReSubmitIntercepter extends HandlerInterceptorAdapter { private static final String SPLIT_FLAG = "_"; private static final String AVOID_RE_SUBMIT_TOKEN_KEY = "identifier_token"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (checkAvoidReSubmitTokenOn(handler,AvoidReSubmitBehavior.Check)) { //验证是否重复 if (checkIsRepeatSubmit(request)) { //重复提交 return false; } } return super.preHandle(request, response, handler); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (checkAvoidReSubmitTokenOn(handler,AvoidReSubmitBehavior.Create)) { Random random = new Random(); String uuid = UUID.randomUUID().toString().replace(SPLIT_FLAG, String.valueOf(random.nextInt(100000))); String tokenValue = String.valueOf(System.currentTimeMillis()); String transferToken = uuid + SPLIT_FLAG + tokenValue; request.setAttribute(AVOID_RE_SUBMIT_TOKEN_KEY, transferToken); request.getSession(true).setAttribute(uuid, tokenValue); } super.postHandle(request, response, handler, modelAndView); } /** * Description: 是否开启防重规则 * * @Author liam * @Create Date: 2018/3/9 10:33 */ private boolean checkAvoidReSubmitTokenOn(Object handler,AvoidReSubmitBehavior behavior) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method invokeMethod = handlerMethod.getMethod(); AvoidReSubmitToken avoidReSubmitToken = invokeMethod.getAnnotation(AvoidReSubmitToken.class); if (avoidReSubmitToken != null && avoidReSubmitToken.behavior().equals(behavior)) { return true; } return false; } private boolean checkIsRepeatSubmit(HttpServletRequest request) { String clientToken = request.getParameter(AVOID_RE_SUBMIT_TOKEN_KEY); if (StringUtils.isEmpty(clientToken)) { clientToken = request.getParameter(AVOID_RE_SUBMIT_TOKEN_KEY); if (StringUtils.isEmpty(clientToken)) { return true; } } String[] clientTokensDetail = StringUtils.split(clientToken, SPLIT_FLAG); if (clientTokensDetail.length == 2) { String uuid = clientTokensDetail[0]; String token = clientTokensDetail[1];
//此处存在并发风险...阔以加锁处理 String serverToken = (String) request.getSession(true).getAttribute(uuid); if (StringUtils.isNotEmpty(serverToken) && token.equals(serverToken)) { request.getSession(true).removeAttribute(uuid); return false; } } return true; } }
提供开启规则的注解:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface AvoidReSubmitToken { AvoidReSubmitBehavior behavior(); }
定义两种行为:
public enum AvoidReSubmitBehavior { Create, Check; }
拦截器的配置:
<!-- 拦截器配置 --> <mvc:interceptors> <!-- 配置Token拦截器,防止用户重复提交数据 --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="liam.AvoidReSubmitIntercepter"/> </mvc:interceptor> </mvc:interceptors>
Java代码使用;
@AvoidReSubmitToken(behavior = AvoidReSubmitBehavior.Create) @RequestMapping("test") public String testPage() { return "form/page"; } @AvoidReSubmitToken(behavior = AvoidReSubmitBehavior.Check) @RequestMapping("potHandler") public String postHandler(){ return "ok"; }
页面代码:
<form id="" class="form-horizontal" action="${ctx}/postHandler" method="post"> ...... <input type="hidden" name="token" value="${identifier_token}"/> <!-- 注:name必须是identifier_token --> ...... </form>
其实该方案也可以验证提交数据是否有效,当然通常是把token放到只读的缓存了。。
伪代码。。没测试呢。。。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash