博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC后台token防重复提交解决方案
阅读量:7135 次
发布时间:2019-06-28

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

本文介绍如何使用token来防止前端重复提交的问题。


目录

  • 1.思路
  • 2.拦截器源码实现
  • 3.注解源码
  • 4.拦截器的配置
  • 5.使用指南
  • 6.结语

思路

1.添加拦截器,拦截需要防重复提交的请求

2.通过注解@Token来添加token/移除token
3.前端页面表单添加(如果是Ajax请求则需要在请求的json数据中添加token值)

核心源码

拦截器源码实现

/** * com.xxx.interceptor.TokenInterceptor.java * Copyright 2018 Lifangyu, Inc. All rights reserved. */package com.xxx.common.interceptor;import org.apache.log4j.Logger;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.lang.reflect.Method;import java.util.Random;import java.util.UUID;/** * Desc:防重复提交的拦截器 * 

* Created by lifangyu on 2018/02/27. */public class TokenInterceptor extends HandlerInterceptorAdapter { Logger logger = Logger.getLogger(TokenInterceptor.class); static String splitFlag = "_"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); Token annotation = method.getAnnotation(Token.class); if (annotation == null) { return true; } boolean needSaveSession = annotation.add(); if (needSaveSession) { Random random = new Random(); String uuid = UUID.randomUUID().toString().replace(splitFlag, String.valueOf(random.nextInt(100000))); String tokenValue = String.valueOf(System.currentTimeMillis()); request.setAttribute("token", uuid + splitFlag + tokenValue); // session 中 token 的key 每次都是变化的[适应浏览器 打开多个带有token的页面不会有覆盖session的key] request.getSession(true).setAttribute(uuid, tokenValue); } boolean needRemoveSession = annotation.remove(); if (needRemoveSession) { if (isRepeatSubmit(request)) { logger.warn("please don't repeat submit,url:" + request.getServletPath()); return false; } String clinetToken = request.getParameter("token"); if (clinetToken != null && clinetToken.indexOf(splitFlag) > -1) { request.getSession(true).removeAttribute(clinetToken.split("_")[0]); } } return true; } else { return super.preHandle(request, response, handler); } } /** * 判断是否是重复提交 * * @param request * @return */ private boolean isRepeatSubmit(HttpServletRequest request) { String clinetToken = request.getParameter("token"); if (clinetToken == null) { return true; } if (clinetToken.indexOf(splitFlag) <= -1) { return false; } String uuid = clinetToken.split("_")[0]; String token = clinetToken.split("_")[1]; String serverToken = (String) request.getSession(true).getAttribute(uuid); if (serverToken == null) { return true; } if (!serverToken.equals(token)) { return true; } return false; }}复制代码

注解源码

/** * com.xxx.interceptor.Token.java * Copyright 2018 Lifangyu, Inc. All rights reserved. */package com.xxx.common.interceptor;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Desc:Token 注解 * 

* Created by lifangyu on 2018/02/27. */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Token { /** * 添加token的开关[true:添加;false:不添加,default:false] * * @return */ boolean add() default false; /** * 移除token的开关[true:删除;false:不删除,default:false] * * @return */ boolean remove() default false;}复制代码

拦截器的配置

在springMVC的servlet配置文件中配置拦截器

复制代码

使用指南

1.在进入页面的controller方法上添加注解@Token(add=true)

@Token(add = true)@RequestMapping("toXxxHtml")public String toXxxHtml(Model mv) {   ......   return "xxx/xxxHtml";}复制代码

2.在页面toXxxHtml.html添加

......
......
复制代码

3.在防止重复提交的controller方法上添加@Token(remove = true)

@Token(remove = true)@RequestMapping("addXxx")public String addXxx() throws Exception {   ......   return "redirect:toXxxHtml.do";}复制代码

结语

到此本文就结束了,欢迎大家继续关注更多Spring案例。

扫描下面二维码,关注我的公众号哦!!!



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

你可能感兴趣的文章
查看进程信息
查看>>
转载:DIV+CSS有可能遇到的问题
查看>>
protocol buffer
查看>>
web常用模块测试用例
查看>>
【转】分布式数据层 TDDL 来自:阿里巴巴
查看>>
swing常用布局
查看>>
#学习笔记#e2e学习使用(二)
查看>>
LeetCode 222.完全二叉树的节点个数(C++)
查看>>
MyBatis(增删改查)
查看>>
.net编译指令
查看>>
java调用python的几种用法(看这篇就够了)
查看>>
20180307-Xen、KVM、VMware、hyper-v等虚拟化技术的比较
查看>>
一个简单的 vue.js 实践教程
查看>>
【批处理】创建快捷方式
查看>>
Android学习笔记(一) 使用选择部件
查看>>
daily scrum: 2012/11/3
查看>>
eclipse导入maven时pom.xml提示miss相关xxx.jar(本地仓库存在相关jar)报错问题
查看>>
日期格式化(类似QQ邮箱中的邮件列表显示日期)
查看>>
java版spring cloud+spring boot+redis社交电子商务平台(八)消息总线(Spring Cloud Bus)
查看>>
2018-2019-2 网络对抗技术 20165303 Exp6 信息搜集与漏洞扫描
查看>>