spring token 令牌 防止表单重复提交
最近项目中需要对表单重复提交作处理 这里整理记录下。
spring 拦截器配置代码:
<mvc:interceptor>
<!-- 防止表单重复提交 token令牌 拦截器 -->
<mvc:mapping path="/**" />
<bean class="com.ptpl.core.interceptor.TokenInterceptor" />
</mvc:interceptor>
图:
拦截器类代码:
package com.ptpl.core.interceptor;
import java.lang.reflect.Method;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.WebUtils;
import com.ptpl.core.annotation.Token;
public class TokenInterceptor extends HandlerInterceptorAdapter{
@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.save();
if(needSaveSession){
WebUtils.setSessionAttribute(request, "token", UUID.randomUUID().toString());
}
boolean needRemoveSession = annotation.remove();
if(needRemoveSession){
if(isRepeatSubmit(request)){
return false;
}
request.getSession(false).removeAttribute("token");
}
}
return true;
}else{
return super.preHandle(request, response, handler);
}
}
private boolean isRepeatSubmit(HttpServletRequest request){
String serverToken = (String) WebUtils.getSessionAttribute(request, "token");
if(serverToken == null){
return true;
}
String clientToken = request.getParameter("token");
if(clientToken == null){
return true;
}
if(!serverToken.equals(clientToken)){
return true;
}
return false;
}
}
图:
token 自定义注解类代码:
package com.ptpl.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @ClassName: Token
* @Description: TODO(token 令牌注解)
* @author cjm
* @date 2017年6月14日 下午7:43:03
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
boolean save() default false;
boolean remove() default false;
}
图:
jsp 代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="http://localhost:8080/ptpjx/test/token.action" method="get">
<input type="text" name="token" value="<%=request.getSession().getAttribute("token") %>" style="width:400px;"/>
<input type="submit" value="提交">
</form>
</body>
</html>
图:
测试controller 代码;
package com.ptpl.controller;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import com.ptpl.core.annotation.Token;
/**
*
* @ClassName: TestController
* @Description: TODO(测试类)
* @author cjm
* @date 2017年3月14日 上午9:55:30
*
*/
@RequestMapping("/test")
@Controller
public class TestController extends BaseController{
@RequestMapping(value = "/testtoken",method = {RequestMethod.GET,RequestMethod.POST})
@Token(save = true)
public void testtoken(HttpServletRequest request ,HttpServletResponse response){
try {
request.getRequestDispatcher("/test.jsp").forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/token",method = {RequestMethod.GET,RequestMethod.POST})
@Token(remove = true)
public void test3423(HttpServletRequest request ,HttpServletResponse response){
System.out.println("=============进来了====================");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("=============进来了dfdend====================");
}
}
图:
完.....