servlet Session防止表单重复提交方法。
可以用js来做,但是只能增加用户的体验,不能完全防止坏人
l 不足:但用户单击”刷新”,或单击”后退”再次提交表单,将导致表单重复提交
<%@ page language=”java” import=”java.util.*” pageEncoding=”utf-8″%>
<!DOCTYPE HTML PUBLIC ”-//W 3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>My JSP ‘form.jsp’ starting page</title>
</head>
<script type=”text/javascript”>
function doSubmit() {
document.getElementByIdx_x(“submit”).disabled = ’disabled’;
return true;
}
</script>
<body>
<form action=”/javaweb07/servlet/Session3″ method=”post” onsubmit=”return doSubmit()”>
用户名:<input type=”text” name=”username”><br>
密 码:<input type=”password” name=”password”><br>
<input id=”submit” type=”submit” value=”注册”><br>
</form>
</body>
</html>
用session做防表单重复提交
FormServlet HandleFormServlet TokenProcessor
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=utf-8″);
PrintWriter out = response.getWriter();
TokenProcessor processor = TokenProcessor.getInstance();
String token = processor.makeToken(); // 令牌
// 制作一个表单
out.write(“<form action=’/javaweb07/servlet/HandleFormServlet’ method=’post’>”);
out.write(“用户名: <input type=’text’ name=’username’ /><br>”);
out.write(“<input type=’hidden’ name=’token’ value=’”+token+”‘ />”);
out.write(“<input type=’submit’ value=’提交’ /><br>”);
out.write(“</form>”);
request.getSession().setAttribute(“token”, token);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=utf-8″);
PrintWriter out = response.getWriter();
request.setCharacterEncoding(“utf-8″);
String username = request.getParameter(“username”);
// 防止重复提交
String token = request.getParameter(“token”);
String sessionToken = (String) request.getSession().getAttribute(“token”);
if(token==null) {
// 不是我的表单提交的数据
System.out.println(“恶意提交的数据”);
return ;
}
if(sessionToken==null) {
// 已经提交过了
System.out.println(“重复提交的数据”);
return ;
}
if(!token.equals(sessionToken)) {
// 不是表单提交的
System.out.println(“恶意提交的数据”);
return ;
}
// 正常提交的数据
System.out.println(“username=” + username);
System.out.println(“正在存入数据库”);
// 将session中令牌移除
request.getSession().setAttribute(“token”, null);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.write(“数据已经存入数据库”);
}
public class TokenProcessor {
// 令牌的产生器, 产生的令牌要求不重复
// 单例
// 私有构造函数
private TokenProcessor() {}
// 创建静态的实例
private static TokenProcessor instance = new TokenProcessor();
// 提供静态共有的方法返回实例
public static TokenProcessor getInstance() {
return instance;
}
// 设计一个方法产生令牌
public String makeToken(){
try {
// 随机数
String token = new Random().nextInt(19999999) + System.currentTimeMillis() + ”";
// 将数据变为一种长度固定的数据
// md5 指纹算法 消息摘要 md5算法是不可逆的
MessageDigest md = MessageDigest.getInstance(“md5″);
byte[] md5 = md.digest(token.getBytes());
// System.out.println(md5.length);
// 将md5转为明文,base64算法
BASE64Encoder encoder = new BASE64Encoder();
String str = encoder.encode(md5);
return str;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
http://blog.sina.com.cn/s/articlelist_1718234983_0_1.html