|
1 javajavaHTMLjavahtmlhtmlhtmlstrutsstruts服务器服务器strutshtmlstrutshtmlServletjspservletjspjavastrutsJavaSErvletjavaservletjspstrutsjavaservletjavajavaservletservletservletjavajavajspscript ,设置一个变量,只答应提交一次。
<script language="script">
var checkSubmitFlg = false;
function checkSubmit() {
if (checkSubmitFlg == true) {
return false;
}
checkSubmitFlg = true;
return true;
}
document.ondblclick = function docondblclick() {
window.event.returnValue = false;
}
document.onclick = function doconclick() {
if (checkSubmitFlg) {
window.event.returnValue = false;
}
}
</script>
<:form action="myAction.do" method="post">
2 仍是script,将提交按钮或者image置为disable
<:form action="myAction.do" method="post"
>
<:image styleId="submitInput" src="images/ok_b.gif" border="0" />
</:form>
3 利用的同步令牌机制
利用同步令牌(Token)机制来解决Web应用中重复提交的题目,也给出了一个参考实现。
基本原理:
端在处理到达的哀求之前,会将哀求中包含的令牌值与保留在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该哀求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保留的旧的令牌进行替代。这样假如用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和真个令牌不一致,从而有效地防止了重复提交的发生。
if (isTokenValid(request, true)) {
// your code here
return mapping.findForward("success");
} else {
saveToken(request);
return mapping.findForward("submitagain");
}
根据用户会话ID和当前系统时间来天生一个独一(对于每个会话)令牌的,详细实现可以参考TokenProcessor类中的generateToken()方法。
1. //验证事务控制令牌,<:form >会自动根据session中标识天生一个隐含input代表令牌,防止两次提交
2. 在action中:
//<input type="hidden" name="org.apache..taglib..TOKEN"
// value="6aa35341f25184fd996c4c918255c3ae">
if (!isTokenValid(request))
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.transaction.token"));
resetToken(request); //删除session中的令牌
3. action有这样的一个方法天生令牌
protected String generateToken(HttpRequest request) {
HttpSession session = request.getSession();
try {
byte id[] = session.getId().getBytes();
byte now[] =
new Long(System.currentTimeMillis()).toString().getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
return (toHex(md.digest()));
} catch (IllegalStateException e) {
return (null);
} catch (NoSuchAlgorithmException e) {
return (null);
}
}
在更新的时候防止按钮重复点击,主要是用Session来做判定
在/中可以
页面
<input type="hidden " name=" <% =com.lims.util.SynchroToken.TOKEN_NAME%> " value =" <%= com.lims.util.SynchroToken.getToken(request)%>" >
SynchroToken.
package com.lims.util;
import org.apache..util.*;
import x..http.*;
import x...*;
import org.apache..action.*;
/**
* <p>Title: SynchroToken </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: NetStar</p>
* @author Jstar
* @version 1.0
* Created in 2004/04/21
*/
public class SynchroToken{
public final static .lang.String TOKEN_NAME = "_token";
public static boolean checkToken (HttpRequest request){
boolean isEqual = false;
HttpSession session = request.getSession ();
String formToken = request.getParameter (TOKEN_NAME);
String sessionToken = (String)session.getAttribute (TOKEN_NAME);
System.out.println ("formToken: " + formToken + " sessionToken: " +
sessionToken);
if (formToken != null && sessionToken == null){
session.setAttribute (TOKEN_NAME, formToken);
isEqual = true;
}
return isEqual;
}
/**
* Insert the method's description here.
* Creation date: (4/19/2004 3:23:25 PM)
* @return .lang.String
* @param request x..http.HttpRequest
*/
public static String getToken (HttpRequest request){
String token = "" + System.currentTimeMillis ();
HttpSession session = request.getSession ();
if (session != null){
session.removeAttribute (TOKEN_NAME);
}
return token;z
}
/**
* Insert the method's description here.
* Creation date: (4/19/2004 3:24:10 PM)
* @return .lang.String
*/
final static .lang.String getTOKEN_NAME (){
return TOKEN_NAME;
}
public static String message (PageContext pageContext, String key) throws
Exception{
return RequestUtils.message (pageContext, null, null, key);
}
}
4 添加中转页面 |
|