您的位置:首页 > 编程语言 > Java开发

springmvc中自己实现的token防表单重复提交,防止二次提交

2015-05-01 16:37 701 查看
代码简介

springmvc中自己实现的token防表单重复提交,防止二次提交!!!
代码片段

一:首先创建一个token处理类  ,这里的类名叫 TokenHandler

private static Logger logger = Logger.getLogger(TokenHandler.class);

static Map<String, String> springmvc_token = new HashMap<String, String>();

//生成一个唯一值的token
@SuppressWarnings("unchecked")
public synchronized static String generateGUID(HttpSession session) {
String token = "";
try {
Object obj =  session.getAttribute("SPRINGMVC.TOKEN");
if(obj!=null)
springmvc_token = (Map<String,String>)session.getAttribute("SPRINGMVC.TOKEN");
token = new BigInteger(165, new Random()).toString(36)
.toUpperCase();
springmvc_token.put(Constants.DEFAULT_TOKEN_NAME + "." + token,token);
session.setAttribute("SPRINGMVC.TOKEN", springmvc_token);
Constants.TOKEN_VALUE = token;

} catch (IllegalStateException e) {
logger.error("generateGUID() mothod find bug,by token session...");
}
return token;
}

//验证表单token值和session中的token值是否一致
@SuppressWarnings("unchecked")
public static boolean validToken(HttpServletRequest request) {
String inputToken = getInputToken(request);

if (inputToken == null) {
logger.warn("token is not valid!inputToken is NULL");
return false;
}

HttpSession session = request.getSession();
Map<String, String> tokenMap = (Map<String, String>)           session.getAttribute("SPRINGMVC.TOKEN");
if (tokenMap == null || tokenMap.size() < 1) {
logger.warn("token is not valid!sessionToken is NULL");
return false;
}
String sessionToken = tokenMap.get(Constants.DEFAULT_TOKEN_NAME + "."
+ inputToken);
if (!inputToken.equals(sessionToken)) {
logger.warn("token is not valid!inputToken='" + inputToken
+ "',sessionToken = '" + sessionToken + "'");
return false;
}
tokenMap.remove(Constants.DEFAULT_TOKEN_NAME + "." + inputToken);
session.setAttribute("SPRINGMVC.TOKEN", tokenMap);

return true;
}

//获取表单中token值
@SuppressWarnings("unchecked")
public static String getInputToken(HttpServletRequest request) {
Map params = request.getParameterMap();

if (!params.containsKey(Constants.DEFAULT_TOKEN_NAME)) {
logger.warn("Could not find token name in params.");
return null;
}

String[] tokens = (String[]) (String[]) params
.get(Constants.DEFAULT_TOKEN_NAME);

if ((tokens == null) || (tokens.length < 1)) {
logger.warn("Got a null or empty token name.");
return null;
}

return tokens[0];
}


代码片段

三 :这是我用到的常量:
public static String DEFAULT_TOKEN_MSG_JSP = "unSubmit.jsp" ;
public static String TOKEN_VALUE ;
public static String DEFAULT_TOKEN_NAME = "springMVC.token";


代码片段

二: 自己实现一个自定义标签 这里我自定义的标签叫: <dy:token/>  (自定义标签的代码实现,我放csdn上了,不会的赶紧去下载,这里我不讲了),页面中使用如下:
1:引入标签库:<%@ taglib prefix="dy" uri="/dy-tags"%>
2:jsp页面中的表单,注意加上token标签!!!如下:

index.jsp!!!

<%@ taglib prefix="dy" uri="/dy-tags"%>
<html>
<head>
<title>spring mvc</title>
</head>
<body>
welcome to spring mvc!<br/>

<form name="mvcForm" action="indexSubmit.do" method="post">
<dy:token/>
username: <input name="username" type="text" value="${user.username}"/>
password: <input name="password" type="text" value="${user.password}"/>
email: <input name="email" type="text" value="${user.email}"/>
<input type="submit" value="提交">
</form>
</body>
</html>


代码片段

四: 我MyController类的以下2个方法要用到token,防止表单重复提交

@RequestMapping(value = "index.do")
public String index(HttpServletRequest request) {

return "index";
}

@RequestMapping(value = "indexSubmit.do", method = RequestMethod.POST)
public String indexSubmit(User user,HttpServletRequest request) {

try {
myService.insert(user);
logger.info("info=新增成功");
} catch (Exception e) {
logger.error("exception:" + e);
}


代码片段

五:以下是我拦截器的实现,注意有两个拦截器,一个生成token,一个验证token。
/**
* @Title
* @author dengyang
* @date 2013-6-4
*/
public class TokenHandlerInterceptor implements HandlerInterceptor{

public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}

public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object arg2, ModelAndView arg3) throws Exception {
TokenHandler.generateGUID(request.getSession());
}

public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object arg2) throws Exception {
return true;
}

}

/**
* @Title
* @author dengyang
* @date 2013-6-4
*/
public class TokenValidInterceptor implements HandlerInterceptor{

public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object arg2, Exception arg3)
throws Exception {
}

public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {

}
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object arg2) throws Exception {
if(!TokenHandler.validToken(request)){
response.sendRedirect(Constants.DEFAULT_TOKEN_MSG_JSP);
return false;
}
return true;
}

}


代码片段

六:ok,这下面是我的spring拦截器配置

<mvc:interceptor>
<mvc:mapping path="/index.do" />-->这个请求返回的是你有token的页面
<bean class="com.dengyang.interceptor.TokenHandlerInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/indexSubmit.do" />-->这个是提交请求
<bean class="com.dengyang.interceptor.TokenValidInterceptor" />
</mvc:interceptor>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: