使用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:
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");
}
}
}
<?
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 >
<! 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 >
<% @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 >
<% @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多了一个隐藏域:
< 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 >
<
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的
{
System.out.println("valid");
return mapping.findForward("ok");
}
进行比较,如果一样,说明不合法.因为我们的操作都是在一个请求会话里
操作的.说明你在重复提交.
如果不一样,说明重新生成了一个唯一的jsessionid(新开一个浏览器),
开启了一个新会话,重新提交,这是合法的.
这样就防止了表单重复提交问题.
源码下载