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会默认选择此拦截器。
主要源码如下:
要是不一致,即token验证无效(即重复提交),将由下述代码处理无效的token
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>