思路
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) { 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;
}
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";
}原文出处:https://www.cnblogs.com/yclimb/p/9934106.html
點擊查看更多內容
為 TA 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦