session 的应用——防止表单重复提交——2.0版
2013-09-10 19:49
344 查看
session 的应用——防止表单重复提交——2.0版(使用了Struts1 中的重复提交组件: TokenProcessor和自定义标签)
Html代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 这里使用的是自定义标签 -->
<%@ taglib prefix="syh" uri="http://java.syh.com/jsp/syh/core"%>
<!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>
<script type="text/javascript">
//点击 "提交" 按钮, 只能点击一次
var flag = true;
function token(btn){
if(flag){
flag = false;
return true;
}else{
alert('已经提交过了');
}
}
/*
下面的JS代码对 IE 不使用,对于 FF
function token2(btn){
if(flag){
btn.disabled = true;
return true;
}
}
*/
</script>
</head>
<body>
<!--
TokenProcessor.getInstance().saveToken(request)
1. 生成一个随机字符串, 可以保证其唯一
2. 把该字符串放在 Session 域中
3. 返回该字符串
-->
<form action="LoginServlet" method="post" id="regForm">
<!-- 这里使用的是自定义标签 -->
<syh:token/>
<table border="1">
<tr>
<td>Name:</td>
<td>
<input type="text" name="name"/>
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<input type="password" name="password"/>
</td>
</tr>
<tr rowspan="2">
<td>
<input type="submit" value="Submit" onclick="return token2(this);"/>
</td>
<td>
<input type="reset" value="Reset"/>
</td>
</tr>
</table>
</form>
</body>
</html>
Html代码
<%@ 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>
注册成功!
</body>
</html>
Html代码
<%@ 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>
<h4>表单已经提交!请不要多次提交!</h4>
</body>
</html>
Java代码
package com.syh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response) ;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Thread.sleep(3000) ;
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
//模拟网速
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//1. 检验 Token 是否可用
boolean flag = TokenProcessor.getInstance().isTokenValid(request) ;
//2. 去除 Session 中的 Token 标记
if(flag) {
TokenProcessor.getInstance().resetToken(request) ;
}else {
System.out.println("重复提交");
request.getRequestDispatcher("/error.jsp").forward(request, response) ;
return ;
}
String name = request.getParameter("name") ;
System.out.println("添加成功-->" + name);
request.getRequestDispatcher("/success.jsp").forward(request, response) ;
}
}
Java代码
package com.syh.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class TokenProcessor extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext) getJspContext();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
String output = "<input type='hidden' name='" + TOKEN_KEY + "' value='" + saveToken(request) + "'/>";
pageContext.getOut().print(output);
}
public static final String TAGLIB_PACKAGE = "org.apache.struts.taglib.html";
public static final String TRANSACTION_TOKEN_KEY =
"org.apache.struts.action.TOKEN";
public static final String TOKEN_KEY = TAGLIB_PACKAGE + ".TOKEN";
private static TokenProcessor instance = new TokenProcessor();
private long previous;
public TokenProcessor() {
super();
}
public static TokenProcessor getInstance() {
return instance;
}
public synchronized boolean isTokenValid(HttpServletRequest request) {
return this.isTokenValid(request, false);
}
public synchronized boolean isTokenValid(HttpServletRequest request,
boolean reset) {
// Retrieve the current session for this request
HttpSession session = request.getSession(false);
if (session == null) {
return false;
}
String saved =
(String) session.getAttribute(TRANSACTION_TOKEN_KEY);
if (saved == null) {
return false;
}
if (reset) {
this.resetToken(request);
}
String token = request.getParameter(TOKEN_KEY);
if (token == null) {
return false;
}
return saved.equals(token);
}
public synchronized void resetToken(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(TRANSACTION_TOKEN_KEY);
}
public synchronized String saveToken(HttpServletRequest request) {
HttpSession session = request.getSession();
String token = generateToken(request);
if (token != null) {
session.setAttribute(TRANSACTION_TOKEN_KEY, token);
}
return token;
}
public synchronized String generateToken(HttpServletRequest request) {
HttpSession session = request.getSession();
return generateToken(session.getId());
}
public synchronized String generateToken(String id) {
try {
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.getBytes());
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();
}
}
Xml代码
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>MyTag 1.0 core</description>
<display-name>MyTag core</display-name>
<tlib-version>1.0</tlib-version>
<short-name>syh</short-name>
<uri>http://java.syh.com/jsp/syh/core</uri>
<tag>
<name>token</name>
<tag-class>com.syh.servlet.TokenProcessor</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
Html代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 这里使用的是自定义标签 -->
<%@ taglib prefix="syh" uri="http://java.syh.com/jsp/syh/core"%>
<!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>
<script type="text/javascript">
//点击 "提交" 按钮, 只能点击一次
var flag = true;
function token(btn){
if(flag){
flag = false;
return true;
}else{
alert('已经提交过了');
}
}
/*
下面的JS代码对 IE 不使用,对于 FF
function token2(btn){
if(flag){
btn.disabled = true;
return true;
}
}
*/
</script>
</head>
<body>
<!--
TokenProcessor.getInstance().saveToken(request)
1. 生成一个随机字符串, 可以保证其唯一
2. 把该字符串放在 Session 域中
3. 返回该字符串
-->
<form action="LoginServlet" method="post" id="regForm">
<!-- 这里使用的是自定义标签 -->
<syh:token/>
<table border="1">
<tr>
<td>Name:</td>
<td>
<input type="text" name="name"/>
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<input type="password" name="password"/>
</td>
</tr>
<tr rowspan="2">
<td>
<input type="submit" value="Submit" onclick="return token2(this);"/>
</td>
<td>
<input type="reset" value="Reset"/>
</td>
</tr>
</table>
</form>
</body>
</html>
Html代码
<%@ 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>
注册成功!
</body>
</html>
Html代码
<%@ 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>
<h4>表单已经提交!请不要多次提交!</h4>
</body>
</html>
Java代码
package com.syh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response) ;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Thread.sleep(3000) ;
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
//模拟网速
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//1. 检验 Token 是否可用
boolean flag = TokenProcessor.getInstance().isTokenValid(request) ;
//2. 去除 Session 中的 Token 标记
if(flag) {
TokenProcessor.getInstance().resetToken(request) ;
}else {
System.out.println("重复提交");
request.getRequestDispatcher("/error.jsp").forward(request, response) ;
return ;
}
String name = request.getParameter("name") ;
System.out.println("添加成功-->" + name);
request.getRequestDispatcher("/success.jsp").forward(request, response) ;
}
}
Java代码
package com.syh.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class TokenProcessor extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext) getJspContext();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
String output = "<input type='hidden' name='" + TOKEN_KEY + "' value='" + saveToken(request) + "'/>";
pageContext.getOut().print(output);
}
public static final String TAGLIB_PACKAGE = "org.apache.struts.taglib.html";
public static final String TRANSACTION_TOKEN_KEY =
"org.apache.struts.action.TOKEN";
public static final String TOKEN_KEY = TAGLIB_PACKAGE + ".TOKEN";
private static TokenProcessor instance = new TokenProcessor();
private long previous;
public TokenProcessor() {
super();
}
public static TokenProcessor getInstance() {
return instance;
}
public synchronized boolean isTokenValid(HttpServletRequest request) {
return this.isTokenValid(request, false);
}
public synchronized boolean isTokenValid(HttpServletRequest request,
boolean reset) {
// Retrieve the current session for this request
HttpSession session = request.getSession(false);
if (session == null) {
return false;
}
String saved =
(String) session.getAttribute(TRANSACTION_TOKEN_KEY);
if (saved == null) {
return false;
}
if (reset) {
this.resetToken(request);
}
String token = request.getParameter(TOKEN_KEY);
if (token == null) {
return false;
}
return saved.equals(token);
}
public synchronized void resetToken(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(TRANSACTION_TOKEN_KEY);
}
public synchronized String saveToken(HttpServletRequest request) {
HttpSession session = request.getSession();
String token = generateToken(request);
if (token != null) {
session.setAttribute(TRANSACTION_TOKEN_KEY, token);
}
return token;
}
public synchronized String generateToken(HttpServletRequest request) {
HttpSession session = request.getSession();
return generateToken(session.getId());
}
public synchronized String generateToken(String id) {
try {
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.getBytes());
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();
}
}
Xml代码
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>MyTag 1.0 core</description>
<display-name>MyTag core</display-name>
<tlib-version>1.0</tlib-version>
<short-name>syh</short-name>
<uri>http://java.syh.com/jsp/syh/core</uri>
<tag>
<name>token</name>
<tag-class>com.syh.servlet.TokenProcessor</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
相关文章推荐
- JavaWeb_session_应用_防止注册表单页面的重复提交
- JavaWeb_session_应用_防止注册表单页面的重复提交
- Session应用之---防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- session令牌防止表单重复提交
- 使用Session防止表单重复提交
- session实现防止用户重复提交表单
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- 利用Session防止表单重复提交
- session的使用:防止表单重复提交
- 使用Session存放Token 防止表单重复提交
- [Java拾遗五]使用Session防止表单重复提交
- JavaWeb学习总结——使用Session防止表单重复提交
- 使用Session防止表单重复提交
- session防止表单重复提交
- javaWeb学习笔记-Session防止表单重复提交
- Session学习:防止用户重复提交表单(单态设计模式-原子设计模式+MD5技术&Base64算法)
- JavaWeb学习总结(十三)——使用Session防止表单重复提交
- JAVAWeb_利用Session防止表单重复提交:10-客户端防表单重复提交和服务器端session防表单重复提交