在注册表单中,我们会遇到表单重复提交
在这里有两种解决方案,一种是在前端阻止,一种在服务器端阻止
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
//定义一个全局变量
//这个变量用来记住表单是否提交过,提交过便置为true
var iscommitted = false;
function dosubmit(){
//当表单为false时 便返回true 并将iscommitted改为true
if(!iscommitted){
iscommitted = true;
return true;
}
return false;
}
</script>
</head>
<body>
<!--
表单添加一个onsubmit事件
该事件调用的方法返回true时便提交表单
-->
<form action="/sd/dfs" method="post" οnsubmit="return dosubmit()">
用户名:<input type="text" name="username" />
<input type="submit" value="提交">
</form>
</body>
</html>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//产生随机数(表单号) 我们需要创建一个随机数的发生器
TokenProcessor instance = TokenProcessor.getInstance();
String token = instance.generateToken();
//将随机数存入session 方便到时候 验证
HttpSession session = request.getSession();
session.setAttribute("token", token);
//请求转发
request.getRequestDispatcher("/form.jsp").forward(request, response);
}
创建一个随机数生产器
//创建一个随机数的发生器
class TokenProcessor{//token:令牌
/*
* 单例设计模式
* 1.把构造方法私有
* 2.自己创建一个
* 3.对外暴露一个方法,允许获取上面创建的对象
*/
private TokenProcessor(){}
private static final TokenProcessor instance = new TokenProcessor();
public static TokenProcessor getInstance(){
return instance;
}
//产生随机数
public String generateToken(){
//获取当前时间 + 随机数
String token = System.currentTimeMillis()+ new Random().nextInt()+"";
try {
//得到数据的摘要(指纹) 创建实例 "md5"算法
MessageDigest md = MessageDigest.getInstance("md5");
byte[] md5 = md.digest(token.getBytes());
/* base64编码
* 然后数经过base64算法编码返回的都是一个明文字符串
* 会把三个字节变成四个字节 每三个字节变成四个字节
*/
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
创建form表单
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/sd/dfs" method="post" >
<input type="hidden" name="token" value="${token}">
用户名:<input type="text" name="username" /><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//判断表单号是否有效
boolean b = isTokenValid(request);
if(!b){
System.out.println("请不要重复提交");
return;
}
request.getSession().removeAttribute("token");
System.out.println("向数据库中注册用户");
}
//判断表单号是否有效
private boolean isTokenValid(HttpServletRequest request) {
//客户机带过来的表单号
String client_token = request.getParameter("token");
if(client_token==null){
return false;
}
//获取session里的表单号
String server_token = (String) request.getSession().getAttribute("token");
if(server_token==null){
return false;
}
//判断客户机的表单号与session里的表单号是否不相等
if(!server_token.equals(client_token)){
return false;
}
return true;
}