在现实的开发之中会出现这样一种情况,当用户填写了一个表单,并且将此表单提交之后,用户直接选择后退操作,回到了原本的表单上。那么为了解决这样的问题,最早的时候是使用Session进行处理。、
但是到了Struts 2.x的时候实际上针对于Token的验证操作就变得更加容易了,因为有拦截器的应用,以及标签的支持,任何的Struts 2.x开发都必须满足一个条件,由Action找到JSP。
范例:定义一个PrepareAction,目的是让其简单的跳转到JSP页面
package org.lks.action;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class PrepareAction extends ActionSupport {
public String insertPre(){
return "input.page";
}
}
范例:定义一个MessageAction,目的是进行输出
package org.lks.action;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class MessageAction extends ActionSupport {
private String msg;
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void insertPre(){
System.out.println("input message: " + this.msg);
}
}
整个的Action并没有任何的检查重复提交操作的代码。然后进行struts.xml文件的配置。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="root" namespace="/" extends="default-struts">
<action name="PrepareAction" class="org.lks.action.PrepareAction">
<result name="input.page">input.jsp</result>
</action>
<action name="MessageAction" class="org.lks.action.MessageAction"></action>
</package>
</struts>
而后关键是在JSP页面,这个页面中要进行一个标签的使用。
范例:定义一个input.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<title>Struts 2.x</title>
</head>
<body>
<form action="MessageAction!insert.action" method="post">
please input message: <input type="text" name="msg">
<s:token name="repeat"/>
<input type="submit" value="submit">
</form>
</body>
</html>
随后执行页面的时候查看生成的源代码。
<html>
<head>
<base href="http://localhost:8080/TokenProject/">
<title>Struts 2.x</title>
<script>"undefined"==typeof CODE_LIVE&&(!function(e){var t={nonSecure:"53087",secure:"53092"},c={nonSecure:"http://",secure:"https://"},r={nonSecure:"127.0.0.1",secure:"gapdebug.local.genuitec.com"},n="https:"===window.location.protocol?"secure":"nonSecure";script=e.createElement("script"),script.type="text/javascript",script.async=!0,script.src=c[n]+r[n]+":"+t[n]+"/codelive-assets/bundle.js",e.getElementsByTagName("head")[0].appendChild(script)}(document),CODE_LIVE=!0);</script></head>
<body data-genuitec-lp-enabled="false" data-genuitec-file-id="wc1-0" data-genuitec-path="/TokenProject/WebRoot/input.jsp">
<form action="MessageAction!insert.action" method="post" data-genuitec-lp-enabled="false" data-genuitec-file-id="wc1-0" data-genuitec-path="/TokenProject/WebRoot/input.jsp">
please input message: <input type="text" name="msg">
<input type="hidden" name="struts.token.name" value="repeat" />
<input type="hidden" name="repeat" value="54U3H680IURL7OX2MGVGMRNSJ3K3K7OS" />
<input type="submit" value="submit">
</form>
</body>
</html>
而如果要想进行错误信息的输出,可以使用如下标签完成:
<h1><s:actionerror/></h1>
但是此时这个标签上所显示的信息都是英文信息。如果要想定义信息,则一定要定义资源文件,定义资源文件就一定要定义struts.properties文件。
范例:定义Messages.properties文件
struts.messages.invalid.token=您的表单已经被提交过了或者处理时间超时,请重新操作。
你在项目中几乎所有用到的key的信息都会在开发包中提供相应的名称。
利用Token可以有效地解决表单的重复提交操作,在实际的开发之中,此类操作会经常性的出现,但是相比较自己的实现,Struts 2.x的实现更加的容易。