您的位置:首页 > 其它

解决后台提交表单数据时,重复F5刷新页面出现重复提交数据的问题。

2017-05-17 15:33 1436 查看
工作原理:页面设置一个key值,添加数据提交时一起传到后台,后台写个TokenProcessor 类,判断每次提交的key值是否相等,不相等让其提交,相等则不让其提交。(每次第一次提交因为第一次生产key所以可以添加)。

1. 添加一个 TokenProcessor 类

package com.ssm.jock.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
1. TokenProcessor类是一个单例类。
*/
public class TokenProcessor
{
static final String TOKEN_KEY="org.sunxin.token";
private static TokenProcessor instance = new TokenProcessor();
/**
* getInstance()方法得到单例类的实例。
*/
public static TokenProcessor getInstance()
{
return instance;
}
/**
* 最近一次生成令牌值的时间戳。
*/
private long previous;
/**
* 判断请求参数中的令牌值是否有效。
*/
public synchronized boolean isTokenValid(HttpServletRequest request)
{
//得到请求的当前Session对象。
HttpSession session = request.getSession(false);
if (session == null)
{
return false;
}
//从Session中取出保存的令牌值。
String saved = (String) session.getAttribute(TOKEN_KEY);
if (saved == null) {
return false;
}
//清除Session中的令牌值。
resetToken(request);
//得到请求参数中的令牌值。
String token = request.getParameter(TOKEN_KEY);
if (token == null) {
return false;
}
return saved.equals(token);
}
/**
* 清除Session中的令牌值。
*/
public synchronized void resetToken(HttpServletRequest request)
{
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(TOKEN_KEY);
}
/**
* 产生一个新的令牌值,保存到Session中,
* 如果当前Session不存在,则创建一个新的Session。
*/
public synchronized void saveToken(HttpServletRequest request)
{
HttpSession session = request.getSession();
String token = generateToken(request);
if (token != null) {
session.setAttribute(TOKEN_KEY, token);
}
}

/**
* 根据用户会话ID和当前的系统时间生成一个唯一的令牌。
*/
public synchronized String generateToken(HttpServletRequest request)
{
HttpSession session = request.getSession();
try
{
byte id[] = session.getId().getBytes();
long current = System.currentTimeMillis();
if (current == previous)
{
current++;
}
previous = current;
byte now[] = new Long(current).toString().getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
return toHex(md.digest());
}
catch (NoSuchAlgorithmException e)
{
return null;
}
}
/**
* 将一个字节数组转换为一个十六进制数字的字符串。
*/
private String toHex(byte buffer[])
{
StringBuffer sb = new StringBuffer(buffer.length * 2);
for (int i = 0; i < buffer.length; i++)
{
sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
}
return sb.toString();
}
/**
* 从Session中得到令牌值,如果Session中没有保存令牌值,
*则生成一个新的令牌值。
*/
public synchronized String getToken(HttpServletRequest request)
{
HttpSession session = request.getSession(false);
if(null==session)
return null;
String token=(String)session.getAttribute(TOKEN_KEY);
if(null==token)
{
token = generateToken(request);
if (token != null)
{
session.setAttribute(TOKEN_KEY, token);
return token;
}
else
return null;
}
else
return token;
}
}


2. JSP页面添加 设置key值

把页面的key值传到后台进行判断

页面顶部设置

<!-- okenProcessor的完全路径  -->
<%@page import="com.ssm.jock.utils.TokenProcessor"%>
<%
TokenProcessor processor =  TokenProcessor.getInstance();
String token = processor.getToken(request);
%>




页面form表单里面添加一个隐藏的text标签保存key值

<input type="hidden" name="org.sunxin.token" value="<%=token%>"/>




3. JAVA控制器判断,值相等不让其添加,不相等让其添加 ( 主要部分 )

//实例化TokenProcessor 类
TokenProcessor processor = TokenProcessor.getInstance();
//获取令牌值,判断是否相等,相等就不让其重复提交
if (!processor.isTokenValid(request)) {
processor.saveToken(request);
}else{
int ret1 = ctuService.insertCouponTypeUser(ctu);
if(ret1 > 0){
out.info("添加成功");
}else{
out.info("添加失败");
}
}


提示:语句必须放在里面,放在前面还是会继续添加数据,因为他是先执行了添加语句,才判断。不放在里面根本没有进行key值判断,还是会继续增加。



此时再次添加数据:就可以防止F5刷新重复提交数据的问题。希望对大家有所帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: