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进行验证操作。