使用token是为了防止重复提交,像灌水之类的.
LoginAction:
package com.web.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
public class LoginAction extends DispatchAction {
public ActionForward get(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//保存令牌(保存在jsp动态生成的32位jsessionid)\
this.saveToken(request);
System.out.println("begin save");
return mapping.findForward("login");
}
public ActionForward login(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
/**//*if(this.isTokenValid(request))
{
System.out.println("valid");
this.resetToken(request);
return mapping.findForward("ok");
}*/
//这个写法和上面注释部分一样效果
if(this.isTokenValid(request,true))
{
System.out.println("valid");
return mapping.findForward("ok");
}
else
{
System.out.println("invalid");
return mapping.findForward("error");
}
}
}
struts-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans>
<form-bean name="loginForm" type="com.web.form.LoginForm"></form-bean>
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings>
<action path="/login" parameter="method" name="loginForm"
type="com.web.action.LoginAction">
<forward name="login" path="/login.jsp" />
<forward name="ok" path="/ok.jsp" />
<forward name="error" path="/error.jsp" />
</action>
</action-mappings>
<message-resources parameter="" />
</struts-config>
index.jsp:
<%@page contentType="text/html; charset=GBK"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
<html>
<head>
<title>My Jsp</title>
</head>
<body>
<a href="${ctx}/login.do?method=get">发言</a>
</body>
</html>
login.jsp:
<%@page contentType="text/html; charset=GBK"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
<html>
<head>
<title>My Jsp</title>
</head>
<body>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!-- 此处必须使用html标签,否则token不能用 -->
<html:form action="login.do?method=login" method="post">
<html:submit value="提交"></html:submit>
</html:form>
</body>
</html>
当你运行第一次的时候,会提示你"成功".
这时我们退到login.jsp查看一下源代码:
<html>
<head>
<title>My Jsp</title>
</head>
<body>
<form name="loginForm" method="post" action="/strutsToken/login.do?method=login">
<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="d7484f95247cf242a6f35107a1c7ac25"></div>
<input type="submit" value="提交">
</form>
</body>
</html>
对比一下我们写的login.jsp多了一个隐藏域:
<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="d7484f95247cf242a6f35107a1c7ac25"></div>
此时生成了一个32位的唯一的JsessionID做为值.
与LoginAction中的get方法的saveToken(request)是一样的.
此句的作用就是把一个jsessionid保存到request范围里.
在我们后退重新调用:
if(this.isTokenValid(request,true))
{
System.out.println("valid");
return mapping.findForward("ok");
}
时,就会拿login.jsp里传过来的jsessionid和request的
进行比较,如果一样,说明不合法.因为我们的操作都是在一个请求会话里
操作的.说明你在重复提交.
如果不一样,说明重新生成了一个唯一的jsessionid(新开一个浏览器),
开启了一个新会话,重新提交,这是合法的.
这样就防止了表单重复提交问题.
源码下载