原文地址:http://goldcreate.blog.sohu.com/91128778.html
当我们在Struts中提交表单后,可以通过会退按钮返回到原来的表单页面,进行重复性提交。这在很多情况下是不允许的。比如当注册用户的表单中,当提交成功后,回退或者按刷新按钮可以再次提交表单,这样造成数据的不一致性,因为数据已经提交。
Struts中可以利用同步令牌机制来解决重复提交表单的问题。在Struts的Action中提供了和同步令牌相关的方法
protected boolean isTokenValid(HttpServletRequest request)
此方法用来判断当前用户会话中存储的令牌值和当前请求参数的令牌值是否一致,如果不一致返回false,一致则返回true。当我们利用Action进行相应调用处理时,就是利用此方法判断令牌值是否一致来决定是否进行处理
protected void saveToken(HttpServletRequest request)
此方法创建一个新的令牌值,将其保存在当前的会话(session)范围内。如果当前的会话对象不存在,则创建会话对象
protected void resetToken(HttpServletRequest request)
此方法对当前会话范围的令牌值进行复位操作,即删除当前会话范围的令牌值
了解了以上方法后,我们就可以在我们的应用中利用这些方法防止表单的重复性提交。例如在此我们实现一个简单的数据增加操作,首先需要显示给用户一个
信息录入表单,显示此录入表单页面前,需要给当前的请求分配一个同步令牌值,并存储在当前的会话范围内。并在当前的录入页面中生成一个隐藏域,令牌值作为
此隐藏域的内容,当用户提交时,控制器获取隐藏域的内容,利用isValidToken方法判断此参数内容是否和会话中存储的令牌值内容匹配,如果不匹配
则进行适当的错误处理
由于要在页面显示前生成此次请求的令牌值,所以通过一个额外的Action生成令牌值,并转发到录入页面,例如在此额外的Action为:PersonAddPreparedAction,此action的配置为:
<action
path="/personAddPrepared"
scope="request"
type="com.frank.action.PersonAddPreparedAction">
<forward name="personAdd" path="/personAdd.jsp" />
</action>
其中包括一个转发路径personAdd,转发到personAdd.jsp(实际的信息录入页面)。在此Action中生成令牌值,转发到录入页面:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
this.saveToken(request);
return mapping.findForward("personAdd");
}
完成了此次操作后,生成了令牌值,并存储在了当前的会话中,转发到personAdd.jsp,开始信息的录入提交。
personAdd.jsp页面非常的简单
<html:errors/>
<html:form action="/person.do?action=add">
personname : <html:text property="personname" value=""/><html:errors property="personname"/><br/>
age : <html:text property="age" value=""/><html:errors property="age"/><br/>
gender : <html:radio property="gender" value="M"/>男
<html:radio property="gender" value="F"/>女
<html:errors property="gender"/><br/>
<html:submit value="ADD"/><html:cancel/>
</html:form>
提交后请求personAction,进行实际的业务操作
PersonAction中的add契约方法完成数据的增加(在此PersonAction继承了DispatchAction),PersonAction的配置如下:
<action
attribute="personForm"
input="/personAdd.jsp"
name="personForm"
parameter="action"
path="/person"
scope="request"
type="com.frank.action.PersonAction">
<forward name="addFail" path="/personAdd.jsp" />
<forward name="addSuccess" path="/personList.jsp" />
</action>
PersonAction的add方法代码如下:
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
PersonForm personForm = (PersonForm) form;// TODO Auto-generated method stub
String personname=personForm.getPersonname();
int age=personForm.getAge();
String gender=personForm.getGender();
PersonRule personRule=new PersonRule();
ActionMessages errors=new ActionMessages();
if(!this.isTokenValid(request)){
this.saveToken(request);
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage("register.error"));
this.saveErrors(request, errors);
return mapping.findForward("addFail");
}else{
this.resetToken(request);
if(personRule.addPerson(personname, age, gender)){
return mapping.findForward("addSuccess");
}else{
return mapping.getInputForward();
}
}
}
此方法首先获取ActionForm的数据内容,然后判断令牌值是否匹配(判断会话中的令牌值和请求参数中的令牌值)。如果不匹配则重新生成令牌
值,并记录错误信息,转发到addFail(即信息录入页面重新录入)。如果匹配则删除当前会话中的令牌值(这样,当点回退或者刷新按钮重复提交时,因为
此时令牌值已经被删除,显然不匹配,则不进行实际的业务操作,即防止了重复提交),完成实际的业务操作。
在属性文件中加入register.error属性,用于保存错误信息
register.error=you already submit form
测试:
从PersonAddPreparedAction控制器转发到注册页面,此时生成了令牌值保存到当前的会话中,查看此页面的源代码,会发现自动生成了隐藏域,同时记录了令牌值,当提交时,此隐藏域的令牌值也会提交,以后即可和存储在当前会话中的令牌值进行比较了
<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="893ffef11148c6569a3c10f2309a0e21">
首次提交时,没有任何的问题,但是点刷新重复提交或者回退到原来页面进行重复提交时,不会提交成功,而是转发到注册页面,提示错误
分享到:
相关推荐
通过以上步骤,Struts1.x的Token机制就能有效地防止重复提交和CSRF攻击。在实际项目中,可以根据具体需求进行适当的调整,例如增加对Ajax请求的支持,或者自定义错误处理逻辑。记住,安全是Web开发中不可忽视的一...
2. **Action类**:在Struts1.x中,控制器由Action类实现。每个Action对应一个用户请求,处理完成后返回一个结果转发到特定的视图。 3. **配置文件**:`struts-config.xml`是Struts1.x的核心配置文件,用于定义...
而Struts1.x的令牌机制(Token)则是防止重复提交、跨页请求攻击的重要手段。在此,我们将深入探讨Struts1.x令牌的使用方法及其背后的原理。 首先,理解为何需要令牌。在Web应用中,用户可能会意外或恶意地多次点击...
4. **防止重复提交**:为了增加安全性,可以设置验证码一次有效,即用户输入验证码后,无论是否正确,都会立即清除session中的验证码,防止恶意用户多次尝试。 5. **优化用户体验**:验证码的设计应考虑用户体验,...
开发者需要了解如何定义Action类,如何使用注解或XML配置文件来配置它们,以及如何使用Execute-and-Redirect模式来防止重复提交。 接下来,Struts 2的配置文件是理解和使用框架的重要部分。可能包括了struts.xml或...
- `<redirect>`: 实现URL重定向,通常用于跳转到外部资源或者防止表单重复提交。 - `<include>`: 用于在页面中嵌入其他页面或资源,提供动态包含的功能。 2. **HTML标签库(HTML Tags)**: - `<html:form>`: 创建...
5. TokenInterceptor防止表单重复提交。 34 6.使用拦截器实现权限验证 35 7.拦截器中的注解 37 8.使用PreResultListener实现回调 39 六、使用标签 40 1.基础表单标签 40 2.单选按钮和复选框: 41 3.三种方式实现下拉...
- 使用Token机制防止重复提交。 - 在`struts.xml`中配置Token拦截器。 - 在Action类中处理Token验证逻辑。 #### 八、杂项 **8.1 常见问题解答** - **问题汇总**:针对Struts2开发过程中常见的问题进行总结和解答...
在Struts 1中,标签库是实现视图层与控制器层交互的重要工具,使得开发者可以方便地在JSP页面中处理用户输入、展示数据和控制流程。 ### 一、STRUTS1.X 工作原理 Struts 1 的工作流程主要包括以下几个步骤: 1. ...
- 在`resources/js/upload.js`文件中添加代码,禁用表单提交按钮,防止用户重复提交。 ```javascript function disableSubmit() { var allInputs = document.forms[0].getElementsByTagName('input'); for (var...
在实际应用中,Struts还提供了一种防止重复提交的机制,这在`Struts令牌防止重复提交.docx`中有所阐述。通过在请求中添加令牌,服务器可以在接收到请求时检查该令牌,如果发现重复的令牌,则拒绝处理,从而避免了因...
Validator框架则是Struts 1.x中的增强功能,允许更灵活的XML配置和可重用的验证规则。 4. **Validator框架** - **ValidatorConfig**:配置文件(如struts-validator.xml或struts-config.xml)定义了验证规则和错误...
- **防止表单重复提交**:为了避免用户误操作导致的多次请求,可以通过令牌机制或JavaScript禁用提交按钮来防止重复提交。 **5. 用户界面组件** - **复选框的使用技巧**:在Struts中处理复选框的数据通常需要使用...
1. **下载Struts 2**:根据教程中的提示,建议下载Struts 2.1.x版本。 2. **安装Eclipse for Java EE**:这是一款强大的IDE,适合Java Web开发。教程中提到了需要下载Eclipse for Java EE,这是为了方便进行Struts 2...
- **token防止表单重复提交**:使用`<s:token>`标签可以生成一个隐藏字段,防止用户多次提交同一个表单。 通过以上内容的学习,可以全面了解Struts2.1框架的核心特性和使用方法,这对于开发者来说是非常宝贵的资源...
- **目的**:防止表单重复提交。 - **实现**:通过在表单中添加一个隐藏字段,并在提交表单前验证该字段的值是否有效。 **文件上传** - **原理**:使用MultipartRequest来处理含有文件的HTTP请求。 - **实现**:...
- 在Struts 1.x中,框架是通过Servlet启动的。 - 在Struts 2中,框架则是通过Filter启动的,这提高了应用的性能和灵活性。 2. **Struts2 Action管理**: - 在Struts2中,Action通常被` strut2-core.jar`提供的包...
`<s:token>` 生成和检查令牌,防止重复提交。 Y. `<s:url>` 创建URL,可以附加参数,例如:`<s:url action="myAction"><s:param name="param1" value="value1" /></s:url>`。 Z. `<s:validate>` 验证表单字段。 ...