`
superich2008
  • 浏览: 324430 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

使用struts同步令牌机制避免表单的重复提交

阅读更多

一、使用方法

1、假设你要提交的叶面为usermesg.jsp。

2、在打开usermesg.jsp的SaveTokenAction中加入saveToken(request),源码如下:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;


public class SaveToken extends Action ...{

/**//* forward name="usermesg" path="/usermesg.jsp" */
private final static String USERMESG = "usermesg";

public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception ...{

// 在session中放入同步令牌
saveToken(request);

// TODO process request and return an ActionForward instance, for example:
// return mapping.findForward(USERMESG);
return mapping.findForward(USERMESG);
}
}
3、在叶面提交的ValidatorAction中加入isTokenValid(request,true)源码如下:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

public class Validator extends Action ...{
private final static String ERROR="error";
private final static String WELCOME="welcome";
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception ...{

// 验证同步令牌
if(isTokenValid(request,true))...{
return mapping.findForward(WELCOME);
}else...{
return mapping.findForward(ERROR);
}
// TODO process request and return an ActionForward instance, for example:
// return mapping.findForward("forward_name");
}
}
4、 使用注意:usermesg.jsp中的form表单必须使用struts的标签<html:form>

二、基本原理

1、在session中放入同步令牌。原理:调用TokenProcessor类的saveToken(HttpServletRequest arg0);源码如下:

在sesssion中放入名称为Globale.TRANSACTION_TOKEN_KEY的同步令牌:token

public synchronized void saveToken(HttpServletRequest request)...{
HttpSession session=request.getSession();
String token=generateToken(request);
if(token!=null)...{
session.setAttribute(Globale.TRANSACTION_TOKEN_KEY,token);
}
}

2、在打开usermesg.jsp时,应用服务器遇到<html:form>时,便会调用FormTag类的renderToken()方法创建hidden元素。源码如下:

protected String renderToken()...{
StringBuffer result=new StringBuffer();
HttpSession session=pageContext.getSession();
if(session!=null)...{
String token=(String)session.getAttribute(Globale.TRANSACTION_TOKEN_KEY);
if(token!=null)...{
result.append("<input type="hidden" name="");
result.append(Constants.TOKEN_KEY);
result.append("" value="");
result.append(token);
if(this.isXhtml)...{
result.append("" />");
}else...{
result.append("" >");
}
}
}
return result.toStriong();
}
hidden元素Constants.TOKEN_KEY的值就是session中的名称为Globale.TRANSACTION_TOKEN_KEY的同步令牌值

3、验证同步令牌,原理:调用TokenProcessor的isTokenValid(HttpServletRequest arg0,boolean arg1)源码如下:

public synchronized boolean isTokenValid(HttpServletRequest request,boolean reset)...{
HttpSession session request.getSession(false);
if(session==null) return false;

String saved=(String)session.getAttribute(Globale.TRANSACTION_TOKEN_KEY);

if(saved==null) return false;

if(reset) this.resetToken(request);


String token=request.getParameter(Constants.TOKEN_KEY);

if(token==null) return false;

return saved.equals(token);
}
从叶面取出同步令牌值和session中的进行比较。如果相等则为第一次,不等就是重复提交。前提就是传进来的参数reset必须是true。不然每次都相同。其中resetToken()方法如下:

public synchronized void resetToken(HttpServletRequest request)...{
HttpSession session request.getSession(false);
if(session==null)...{
return;
}
session.removeAttribute(Globale.TRANSACTION_TOKEN_KEY);
}
这就是在isTokenValid方法中boolean参数的作用:清除session中的同步令牌,避免重复提交。如果把true改为false 将不会起到避免重复提交的作用

分享到:
评论

相关推荐

    使用struts的同步令牌避免form的重复提交

    ### 使用Struts的同步令牌避免表单重复提交 #### 一、使用方法 为了有效地防止Web应用程序中的表单重复提交问题,Struts框架提供了一种简单而强大的解决方案——同步令牌模式(Synchronization Token Pattern, STP...

    Servlet、Struts、SpringMVC对于表单重复提交的解决方案

    总结来说,Servlet、Struts和SpringMVC都提供了各自的解决方案来防止表单重复提交,主要方法包括使用Session、令牌机制、重定向和拦截器等。开发者可以根据项目需求选择合适的方式来实现,确保应用的稳定性和数据...

    JSP避免Form重复提交的三种方案

    JSP 避免 Form 重复提交的三种方案 ...JSP 避免 Form 重复提交的三种方案可以选择使用 JavaScript 设置提交标志、禁用提交按钮或使用 Struts 的同步令牌机制,具体选择哪种方法取决于项目的需求和实现难度。

    Web应用中避免Form重复提交的三种方案

    Struts同步令牌机制** 对于使用Struts框架的Web应用程序,可以采用其内置的同步令牌机制来防止重复提交。Struts提供了一种简单而有效的方法来管理这一过程。 **实现原理**: - **初始化阶段**: 当用户首次访问...

    JSP避免Form重复提交的三种方案.docx

    3. Struts同步令牌机制: Struts框架提供了一种基于令牌的解决方案,以服务器端验证为主。其工作原理是:服务器在处理请求前,对比请求中的令牌与用户会话中的令牌是否匹配。处理后,服务器会生成新的令牌并更新...

    Java怎样防止重复提交

    每个表单提交时附带一个与Session中保存的令牌相匹配的令牌,提交后更新Session中的令牌,使得下一次提交的令牌无法匹配,从而避免重复处理。 6. **HTTP状态码和重定向**: - 在处理完请求后,服务器可以发送303 ...

    BBS论坛的详细设计

    BBS 论坛的详细设计 本文档将详细介绍 BBS 论坛的设计,涵盖 MVC ...为了解决 Web 应用中重复提交的问题,我们使用 Struts 的同步令牌机制(token)解决问题。在本项目中,我们主要是针对 BBS 发表的表单进行限制。

    ExtJs 与 Structs2交互的几大总结

    Struts2提供了一些安全插件和配置,如使用过滤器防止XSS攻击,添加CSRF令牌防止非法请求。 9. **调试与日志**:在调试过程中,可以使用浏览器的开发者工具查看网络请求和响应,以及Struts2的Action和Result的日志,...

    单点登录(SingleSignOn-SSO)完整案例

    3. **令牌分发**:将令牌发送到需要SSO功能的所有应用系统,通常是通过Cookie或者隐藏的表单字段。 4. **验证令牌**:用户访问其他应用时,应用系统会检查用户请求中携带的令牌,通过与身份验证中心的交互确认令牌的...

    AJAX FAQ for the Java Developer.doc

    这通常涉及到监听表单的提交事件,阻止默认的行为,然后使用AJAX请求将表单数据发送到服务器。服务器处理完数据后,可以使用响应更新页面的局部区域,从而提供流畅的用户体验。 17. **服务器还是客户端控制** 在...

    realmethods框架手册

    4. **JSP同步令牌策略** - **令牌产生**: JSP页面会生成一个唯一的令牌,确保每次请求的合法性。 - **令牌验证**: 在表单提交时,服务器端会验证请求中的令牌是否与生成的令牌一致,从而防止CSRF攻击。 5. **应用...

    spring security 参考手册中文版

    18.2同步器令牌模式 141 18.3何时使用CSRF保护 142 18.3.1 CSRF保护和JSON 142 18.3.2 CSRF和无状态浏览器应用程序 143 18.4使用Spring Security CSRF保护 143 18.4.1使用适当的HTTP动词 144 18.4.2配置CSRF保护 144...

Global site tag (gtag.js) - Google Analytics