工程目录结构:
主要代码:
令牌类:
package com.mth.token;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import sun.misc.BASE64Encoder;
/**
*
* @ClassName: Token 单例
* @Description: 产生一个令牌 MessageDigest BASE64Encoder
* @author mth 75100313@qq.com
* @date 2014-3-20 上午08:15:33
*
*/
public class Token {
private static final Token tokenInstance = new Token();
private Token() {
super();
// TODO Auto-generated constructor stub
}
public static Token getInstance(){
return tokenInstance;
}
public String getToken() {
//生成随机值
String token = System.currentTimeMillis() + new Random().nextInt() + "";
MessageDigest md;
try {
//得到数据摘要
md = MessageDigest.getInstance("md5");
byte[] md5 = md.digest(token.getBytes());
//编码
BASE64Encoder encoder = new BASE64Encoder();
String str = encoder.encode(md5);
return str;
} catch (NoSuchAlgorithmException e) {
new RuntimeException(e);
}
return null;
}
}
表单servlet(跳转到form.jsp)
package com.mth.form;
import java.io.IOException;
import java.security.MessageDigest;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mth.token.Token;
/**
*
* @ClassName: FormServlet
* @Description: 通过这个servlet来把令牌发送到前台的隐藏域
* @author mth 75100313@qq.com
* @date 2014-3-20 上午09:03:56
*
*/
public class FormServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获得一个编码
Token token = Token.getInstance();
String str = token.getToken();
request.getSession().setAttribute("token", str);
request.getRequestDispatcher("/form.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
处理重复提交(打印一句话 没连数据库)
package com.mth.form;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @ClassName: CheckForm
* @Description: 处理表单重复提交
* @author mth 75100313@qq.com
* @date 2014-3-20 上午08:39:47
*
*/
public class CheckForm extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
boolean b = check(request);
if (b) {
request.getSession().removeAttribute("token");
System.out.println("注册成功过!");
} else {
System.out.println("请不要重复登陆!");
}
}
/**
*
* @Title: check
* @Description:检查表单是否有效
* @param @param request
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
private boolean check(HttpServletRequest request) {
//获得隐藏域的值
String hidden = request.getParameter("hidden");
String token = (String) request.getSession().getAttribute("token");
//直接登陆情况直接到form.jsp页面登陆此时hidden值为""
if (hidden == null || "".equals(hidden)) {
System.out.println("不能直接登陆");
return false;
}
//服务器端没有这个令牌
if (token == null) {
System.out.println("服务器端没有了 已经提交过");
return false;
}
//服务器和隐藏域的值不等
if (!hidden.equals(token)) {
System.out.println("不相等 ,不能登陆");
return false;
}
return true;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
form.jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>服务器端防止表单重复提交</title>
</head>
<body>
<form action="/FromSubmitMore/CheckForm" method="post">
<input type="hidden" name="hidden" value="${token }">
用户名:
<input type="text">
<br />
<input type="submit" value="login">
</form>
</body>
</html>