struts2---防重复提交解析

本文详细介绍了在Struts2框架中如何通过在submit标签前添加<s:token/>标签来防止表单的重复提交。具体步骤包括在jsp页面生成隐藏输入标签用于存储token值,配置token拦截器验证token的有效性,并在action处理中设置相应的result视图来处理无效token的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

struts2 中防表单刷新,再strut2中防表单刷新主要有三步:
1.在submit标签前加上<s:token />标签
此标签会在jsp页面上生成如下两个标签:
<input type="hidden" name="struts.token.name" value="token" />
<input type="hidden" name="token" value="NLCQVRVSY0FUB6HXMQ31ISUK9BEA1ST6" />
这两个标签中,第一个标签将会以"struts.token.name为属性名,存入到session域中,其值为
首次提交时第二个标签的随机值。第二个标签在每次提交时都会变化。这样在重复提交时,struts2
底层实现是利用第二个标签的值与session中的struts.token.name来进行比较,要是不一致则认为是
重复提交操作,将会返回一个invalid.token视图名。

2.在struts.xml配置文件中,配置token拦截器
<interceptor-ref name="token" />
<interceptor-ref name="defaultStack"/>
第一个拦截器为token拦截器,它将主要负责验证步骤一种token值是否有效(相等为有效,不相等
为无效). 第二个拦截器为默认拦截器,当不配置时,struts2会默认选择此拦截器。
主要源码如下:
public static boolean validToken() {
					String tokenName = getTokenName(); //获取步骤一中名为token的hidden标签


					...


					String token = getToken(tokenName);//获取其生成的随机值


					...
					//从session中获取名为struts.token.name的属性值
					Map session = ActionContext.getContext().getSession();
					String tokenSessionName = buildTokenSessionAttributeName(tokenName);
					String sessionToken = (String) session.get(tokenSessionName);
					
					//比较两个值是否相等
					if (!token.equals(sessionToken)) {
						if (LOG.isWarnEnabled()) {
							LOG.warn(LocalizedTextUtil.findText(TokenHelper.class, "struts.internal.invalid.token", ActionContext.getContext().getLocale(), "Form token {0} does not match the session token {1}.", new Object[]{
									token, sessionToken
							}));
						}


						return false;
					}
					
					// remove the token so it won't be used again
					session.remove(tokenSessionName);


					return true;
				}


要是不一致,即token验证无效(即重复提交),将由下述代码处理无效的token
protected String handleInvalidToken(ActionInvocation invocation) throws Exception {
					Object action = invocation.getAction(); //获取处理的action
					String errorMessage = getErrorMessage(invocation); //获取错误提示信息,可以通过
					//配置国际化资源,从其中获取(资源属性名为struts.messages.invalid.token)


					if (action instanceof ValidationAware) {
						((ValidationAware) action).addActionError(errorMessage);
					} else {
						log.warn(errorMessage);
					}
					//返回一个视图名为invalid.token的字符串
					return INVALID_TOKEN_CODE;
				}
				
				protected String getErrorMessage(ActionInvocation invocation) {
					Object action = invocation.getAction();
					if (action instanceof TextProvider) {
						return ((TextProvider) action).getText(INVALID_TOKEN_MESSAGE_KEY, DEFAULT_ERROR_MESSAGE);
					}
					return textProvider.getText(INVALID_TOKEN_MESSAGE_KEY, DEFAULT_ERROR_MESSAGE);
				}


3. 在处理提交的action中编写一个名为invalid.token的result视图


示例:

jsp

<s:form action="addUser">
	  	<s:textfield name="name" label="用户名"/>	<br />
	  	<s:textfield name="age" label="年龄"/><br />
	  	<s:token />
	  	<s:submit value="添加"/>
	  </s:form>

struts2.xml配置文件

<action name="addUser" class="cn.itcast.action.AddUserAction">
		  <interceptor-ref name="token" />
		  <interceptor-ref name="defaultStack"/>
		  <result type="chain">listUser</result>
		  <result name="invalid.token">/jsp/norefresh.jsp</result>
		</action>
		
		<action name="listUser" class="cn.itcast.action.ListUserAction">
		  <result>/jsp/listUser.jsp</result>
		  
		</action>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值