Token主要是以一种指令牌的形式进行重复提交处理的,在很多情况下,如果用户对同一个
表单进行了多次提交,则有可能造成数据的混乱,此时Web服务器必须对这种重提提交的行为进
行处理。例如:如果现在是一个用户注册的操作,如果用户已经提交过了表单,而且服务器端已
经对这次的操作进行了成功的处理,而此时的用户通过浏览器执行了后退操作之后,并且对表单
再次提交,服务器端就应该及时地识别这些用户的错误操作,并进行相应的错误处理,防止用户
的重复提交。
一.Token的原理
设置Token就是向session中保存一个属性,而判断Token就是从session中取出属性对内容
进行验证,如果验证成功,则正常操作;如果验证失败,则进行相应的错误处理。但是,这种纯粹
地依靠手工的方式进行验证非常的麻烦,所以Struts中专门提供了Token的支持。
方法 | 类型 | 描述 |
protected boolean isTokenValid(HttpServletRequest
request)
| 普通 | 判断Token是否存在,如果存在则返回true,如果不存在则返回false |
protected void saveToken(HttpServletRequest
request)
| 普通 | 设置Token |
protected void resetToken(HttpServletRequest
request)
| 普通 | 删除Token |
二.设计一个Token的程序
sf.jsp -- > tokenAction -- > return mapping.findForward("input") -- >
sg.jsp -- > inputAction --> return mapping.getInputForward()
sf.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean"
prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html"
prefix="html"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic"
prefix="logic"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>sf.jsp</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h3>
<a href="tokenforward.do">获取Token,输入数据</a>
</h3>
</body>
</html>
TokenForwardForm:
package com.zyy.struts.form;
import org.apache.struts.action.ActionForm;
public class TokenForwardForm extends ActionForm {
}
TokenForwardAction:
package com.zyy.struts.action;
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 TokenForwardAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 设置token
super.saveToken(request);
return mapping.findForward("input");
}
}
sg.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean"
prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html"
prefix="html"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic"
prefix="logic"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>sg.jsp</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<html:messages id="token">
<h2>
<font color="red">${token }</font>
</h2>
</html:messages>
<html:form action="/jsp/input.do" method="post">
<html:text property="message"></html:text>
<html:submit value="显示"></html:submit>
</html:form>
</body>
</html>
InputForm:
package com.zyy.struts.form;
import org.apache.struts.action.ActionForm;
public class InputForm extends ActionForm {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
InputAction:
package com.zyy.struts.action;
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;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import com.zyy.struts.form.InputForm;
public class InputAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
InputForm inputForm = (InputForm) (form);
// 如果设置的Token正确,则输出内容
if (super.isTokenValid(request)) {
System.out.println("内容:" + inputForm.getMessage());
// 取消Token设置
super.resetToken(request);
} else {
ActionMessages errors = new ActionMessages();
errors.add("token", new ActionMessage("error.token"));
// 保存错误信息
this.saveErrors(request, errors);
return mapping.getInputForward();
}
return null;
}
}
struts-config.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="tokenForwardForm" type="com.zyy.struts.form.TokenForwardForm"></form-bean>
<form-bean name="inputForm" type="com.zyy.struts.form.InputForm"></form-bean>
</form-beans>
<global-exceptions>
</global-exceptions>
<global-forwards>
</global-forwards>
<action-mappings>
<action path="/jsp/tokenforward" attribute="tokenForwardForm" input="/jsp/sg.jsp"
name="tokenForwardForm" scope="request" type="com.zyy.struts.action.TokenForwardAction">
<forward name="input" path="/jsp/sg.jsp"></forward>
</action>
<action path="/jsp/input" attribute="inputForm" input="/jsp/sg.jsp"
name="inputForm" scope="request" type="com.zyy.struts.action.InputAction">
</action>
</action-mappings>
<message-resources parameter="resource.MessageResources" />
</struts-config>
资源文件:
执行:
点击后:
提交后:
后退之后,再提交:
不难发现,使用Token可以有效地减少重复提交的操作,能够保证程序运行的正确性。所以:
只要涉及到输入数据的操作,建议尽可能使用Token进行验证操作。