一、使用方法
1
、
假如你要提交的页面为toSubmit.jsp
;
2
、
在打开toSubmit.jsp
的Action1
中加入:saveToken(request)
,例如
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
//
生成同步令牌
saveToken(request);
return
mapping.findForward("toSubmit");
}
|
3
、
在提交toSubmit.jsp
的Action2
中加入:isTokenValid(request, true)
,例如:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
//
验证同步令牌
if
(isTokenValid(request, true)) {
//
执行提交操作
}else {
//
重复提交
return mapping.findForward("Error");
}
}
|
4
、
使用注意:toSubmit.jsp
中的form
必须使用struts
的标签<html:form>
。
二、基本原理
第一步、在session
中放入同步令牌
在Action1
中加入了saveToken(request)
的方法后,调用TokenProcessor
类的saveToken
方法如下:
public synchronized void saveToken(HttpServletRequest
request) {
HttpSession session =
request.getSession();
String token =
generateToken(request);
if (token != null) {
session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);
}
}
|
很明显在session
中放入了同步令牌,名称为Globals.TRANSACTION_TOKEN_KEY
。
第二步、在页面创建hidden
元素
当应用服务器初始化toSubmit.jsp
页面遇到标签<html:form>
时,便会调用struts
的FormTag
类,其中有一个方法:
protected String renderToken() {
StringBuffer results = new
StringBuffer();
HttpSession session =
pageContext.getSession();
if (session != null) {
String token
=
(String)
session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
if (token !=
null) {
results.append("<input type=\"hidden\" name=\"");
results.append(Constants.TOKEN_KEY);
results.append("\" value=\"");
results.append(token);
if (this.isXhtml()) {
results.append("\" />");
} else {
results.append("\">");
}
}
}
return results.toString();
}
|
其意为:当检测到session
中的Globals.TRANSACTION_TOKEN_KEY
不为空时,在toSubmit.jsp
页面创建元素:
<input type="hidden"
name="org.apache.struts.taglib.html.TOKEN" value="">
|
名称为:org.apache.struts.taglib.html.TOKEN
就是Constants.TOKEN_KEY
;
值为:session
中的Globals.TRANSACTION_TOKEN_KEY
的值,即为同步令牌值。
第三步、验证同步令牌
在Action2
中加入isTokenValid
方法,实际上是调用TokenProcessor
类的isTokenValid
方法如下:
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;
}
// Retrieve the transaction token
from this session, and
// reset it if requested
String saved = (String)
session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
if (saved == null) {
return
false;
}
if (reset) {
this.resetToken(request);
}
// Retrieve the transaction token
included in this request
String token =
request.getParameter(Constants.TOKEN_KEY);
if (token == null) {
return
false;
}
return saved.equals(token);
}
|
它首先取得session
中的令牌值,然后resetToken
,再从页面hidden
元素取来令牌值,进行比较,如果相等则为第一次,不等则为重复提交。
其中resetToken
方法如下:
public synchronized void resetToken(HttpServletRequest
request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(Globals.TRANSACTION_TOKEN_KEY);
|
分享到:
相关推荐
JSP 避免 Form 重复提交的三种方案 ...JSP 避免 Form 重复提交的三种方案可以选择使用 JavaScript 设置提交标志、禁用提交按钮或使用 Struts 的同步令牌机制,具体选择哪种方法取决于项目的需求和实现难度。
Struts同步令牌机制** 对于使用Struts框架的Web应用程序,可以采用其内置的同步令牌机制来防止重复提交。Struts提供了一种简单而有效的方法来管理这一过程。 **实现原理**: - **初始化阶段**: 当用户首次访问...
3. Struts同步令牌机制: Struts框架提供了一种基于令牌的解决方案,以服务器端验证为主。其工作原理是:服务器在处理请求前,对比请求中的令牌与用户会话中的令牌是否匹配。处理后,服务器会生成新的令牌并更新...
总结来说,Servlet、Struts和SpringMVC都提供了各自的解决方案来防止表单重复提交,主要方法包括使用Session、令牌机制、重定向和拦截器等。开发者可以根据项目需求选择合适的方式来实现,确保应用的稳定性和数据...
BBS 论坛的详细设计 本文档将详细介绍 BBS 论坛的设计,涵盖 MVC ...为了解决 Web 应用中重复提交的问题,我们使用 Struts 的同步令牌机制(token)解决问题。在本项目中,我们主要是针对 BBS 发表的表单进行限制。
4. **JSP同步令牌策略** - **令牌产生**: JSP页面会生成一个唯一的令牌,确保每次请求的合法性。 - **令牌验证**: 在表单提交时,服务器端会验证请求中的令牌是否与生成的令牌一致,从而防止CSRF攻击。 5. **应用...
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...