内容简介:1.添加拦截器,拦截需要防重复提交的请求2.通过注解@Token来添加token/移除token3.前端页面表单添加(如果是Ajax请求则需要在请求的json数据中添加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:防重复提交的拦截器
* <p>
* 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) {
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) {
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 注解
* <p>
* 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配置文件中配置拦截器
<!-- 拦截器配置 --> <mvc:interceptors> <!-- 配置Token拦截器,防止用户重复提交数据 --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.xxx.interceptor.TokenInterceptor"/> </mvc:interceptor> </mvc:interceptors> 复制代码
使用指南
1.在进入页面的controller方法上添加注解@Token(add=true)
@Token(add = true)
@RequestMapping("toXxxHtml")
public String toXxxHtml(Model mv) {
......
return "xxx/xxxHtml";
}
复制代码
2.在页面toXxxHtml.html添加
<form id="xxx_submit_form" class="form-horizontal" action="${ctx}/xxx/addXxx.do" method="post">
......
<!-- 注:name必须是token -->
<input type="hidden" name="token" value="${token!''}"/>
......
</form>
复制代码
3.在防止重复提交的controller方法上添加@Token(remove = true)
@Token(remove = true)
@RequestMapping("addXxx")
public String addXxx() throws Exception {
......
return "redirect:toXxxHtml.do";
}
复制代码
以上所述就是小编给大家介绍的《SpringMVC后台token防重复提交解决方案》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Git提交错误时如何删除Git提交记录
- 分布式系统 - 两段式提交(2PC)和三段式提交(3PC)
- 减半前,比特币开发者代码提交数创历史新高:4月累计提交510次
- 提交任务到Spark
- [译] Commit 提交指南
- Git合并提交
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Designer Idea
梁景红 / 电子工业出版社 / 2006年 / ¥55.00
这是一本以“目的、信息、设计、创意”作为根脉的关于网页视觉的书籍,畅谈的话题从策划到编辑再到设计,从而讨论“我们要建立怎样的站点,并以何种形式完成它”的问题。 全书共分四个部分,分别是网站建设目的,网站信息内容,页面形式设计,网页创作构思。 四部分有机地结合,形成一个统一的整体。“目的”部分以建设网站的目的为主,带领设计师从建站目的的角度,探讨如何抓住首要问题;如何建立网站雏形;如何打开狭隘的、局......一起来看看 《Web Designer Idea》 这本书的介绍吧!