文档库 最新最全的文档下载
当前位置:文档库 › Struts2自定义拦截器实现防止重复提交

Struts2自定义拦截器实现防止重复提交

Struts2自定义拦截器实现防止重复提交
Struts2自定义拦截器实现防止重复提交

由于struts2标签的性能不好,项目组决定不使用,但是如果用struts2自带的拦截器防止重复提交又必须struts标签,所以只好自定拦器实现,具体步骤如下:

新建拦截器类:

public class TokenAtionInterceptor extends AbstractInterceptor {

public String intercept(ActionInvocation invocation) throws Exception {

Map session =

invocation.getInvocationContext().getSession();

HttpServletRequest request = ServletActionContext.getRequest();

String strGUID = RandomGUIDUtil.newGuid();

//生成令牌

String strRequestToken = (String)session.get("request_token");

//取出会话中的令牌

String strToken = request.getParameter("token"); //页面中的令牌

if(strRequestToken != null

&& !strRequestToken.equals(strToken)){ //重复提交,重置令牌

session.put("request_token", strGUID);

request.setAttribute("token", strGUID);

return"invalidToken";

}

session.put("request_token", strGUID);

request.setAttribute("token", strGUID);

return invocation.invoke(); //否则正常运行

}

}

建一个生成令牌的工具类:

public class RandomGUIDUtil extends Object {

/**日志管理类对象*/

private Logger logger= Logger.getLogger(this.getClass().getName());

public String valueBeforeMD5 = "";

public String valueAfterMD5 = "";

private static Random myRand;

private static SecureRandom mySecureRand;

private static String s_id;

/*

* 静态块初始化

*/

static {

mySecureRand = new SecureRandom();

long secureInitializer = mySecureRand.nextLong();

myRand = new Random(secureInitializer);

try {

s_id = InetAddress.getLocalHost().toString();

} catch (UnknownHostException e) {

System.out.println("构造带指定详细消息和嵌入异常!");

}

}

public RandomGUIDUtil() throws Exception {

getRandomGUID(false);

}

public RandomGUIDUtil(boolean secure) throws Exception { getRandomGUID(secure);

}

/*

* 随机生成GUID

*/

private void getRandomGUID(boolean secure) throws Exception { MessageDigest md5 = null;

StringBuffer sbValueBeforeMD5 = new StringBuffer();

try {

md5 = MessageDigest.getInstance("MD5");

} catch (NoSuchAlgorithmException e) {

logger.error("初始化MD5出错!");

throw new NoSuchAlgorithmException("初始化MD5出错!");

}

try {

long time = System.currentTimeMillis();

long rand = 0;

if (secure) {

rand = mySecureRand.nextLong();

} else {

rand = myRand.nextLong();

}

sbValueBeforeMD5.append(s_id);

sbValueBeforeMD5.append(":");

sbValueBeforeMD5.append(Long.toString(time));

sbValueBeforeMD5.append(":");

sbValueBeforeMD5.append(Long.toString(rand));

valueBeforeMD5 = sbValueBeforeMD5.toString();

md5.update(valueBeforeMD5.getBytes());

byte[] array = md5.digest();

StringBuffer sb = new StringBuffer();

for (int j = 0; j < array.length; ++j) {

int b = array[j] & 0xFF;

if (b < 0x10) sb.append('0');

sb.append(Integer.toHexString(b));

}

valueAfterMD5 = sb.toString();

} catch (Exception e) {

logger.error("获得MD5加密码出错!");

throw new Exception("初始化MD5出错!");

}

}

/**

*生成一个GUID串

*@return GUID

*@throws Exception

*/

public static String newGuid() throws Exception{ RandomGUIDUtil rdmGUID = new RandomGUIDUtil();

return rdmGUID.toString();

}

/*

* 生成以主机串号、显卡串号、主板号,以保证唯一性的32位编码

*/

public String toString() {

String raw = valueAfterMD5.toUpperCase();

StringBuffer sb = new StringBuffer();

sb.append(raw.substring(0, 8));

sb.append(raw.substring(8, 12));

sb.append(raw.substring(12, 16));

sb.append(raw.substring(16, 20));

sb.append(raw.substring(20));

return sb.toString();

}

}

在struts配置文件中对应的包下定义拦截器,注意顺序,

package里元素必须按照一定的顺序排列。这个顺序

就是

result-types

interceptors

default-interceptor-ref

default-action-ref

default-class-ref

global-results

global-exception-mappings

action*(就是所有的action放到最后)

配置中加上名为” invalidToken”的result,就是拦截器中,重复提交跳转的路径如:

class="com.tydic.ppm.util.TokenAtionInterceptor">

/error.jsp

/openError.jsp

/content/templateManage/configTemplate/templateBaseInfo.jsp

/content/templateManage/configTemplate/templateBaseInfo.jsp

/content/templateManage/configTemplate/templateBaseInfo.jsp

最后在页面上加一个隐藏域,用来保存页面令牌的,如:

经过上面的步骤就可以实现防止重复提交了,要注意拦截器在struts配置文件中定义的位置。

SCME_STRUTS2试卷

--------------------------------------装--------------------------------------订------------------------------线---------------------------------------- **学院课程考试试卷 课程名称:《使用Struts2开发基于MVC设计模式的企业级应用》(A)卷 年级:班级: 姓名:_______________ 学号:_________________ 考试(考查) 闭卷 选择题(每题2分,共计100分) 1.在控制器类中一般需要添加相应属性的( A )和(C )。(选两项) A.setter方法 B.as方法 C.getter方法 D.is方法 2.业务控制器需要在( B )配置文件中进行配置 A.web.xml B.struts.xml C.struts2.xml D.webwork.xml 3.不属于Struts 2表单标签库的是( D )。 A. B. C. D.