Struts2系列:(13)防表单重复提交(token + 拦截器)

1、原理

服务器端和客户端通过token(令牌)来进行验证:

(1)Browser向Tomcat服务器请求填写表单

(2)Tomcat服务器将带有token的表单返回给Browser

(3)浏览器端在提交时,将form和token一起发送到服务器

(4)Tomcat服务器对Browser进行验证

2、基本步骤

基本步骤如下:

第一步:写好Action,在struts.xml为接受该表单提交请求的action配置token拦截器【服务器】

<action name="student_*" class="com.rupeng.action.StudentAction" method="{1}">
	<interceptor-ref name="defaultStack"/>
	<!-- 增加token拦截器 -->
	<interceptor-ref name="token">
		<!-- 定义被token拦截器拦截的方法 -->
		<param name=“includeMethods">add</param>
	</interceptor-ref>    
	<!-- 当表单重复提交时转向的页面 -->
	<result name="invalid.token">/WEB-INF/page/resubmitError.jsp</result>  
</action>

第二步:在form中使用标签token【浏览器】

<s:form action="student_add" method="post" namespace="/test">
	<s:textfield name="name/><br>
	<s:textfield name="degree/><br>
	<s:token/><s:submit/>
</s:form>

第三步:处理错误【浏览器】

使用<s:actionerror>在出错处理页面中提示错误信息,

在配置中加入了“token”拦截器和“invalid.token”结果,当“token”拦截器发现会话token与请求token不一致时,将直接返回“invalid.token”结果。

3、示例

(1)Action类:StudentAction.java

package com.rk.strut.h_token;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class StudentAction extends ActionSupport
{
	private String username;
	private String password;
	public String getUsername()
	{
		return username;
	}
	public void setUsername(String username)
	{
		this.username = username;
	}
	public String getPassword()
	{
		return password;
	}
	public void setPassword(String password)
	{
		this.password = password;
	}

	public String add()
	{
		HttpServletRequest request = ServletActionContext.getRequest();
		request.setAttribute("user", username);
		request.setAttribute("pwd", password);
		return "success";
	}
}

(2)进行配置struts-token.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<package name="rk_token" namespace="/rk/token" extends="struts-default">
		<action name="add" class="com.rk.strut.h_token.StudentAction" method="add">
			<interceptor-ref name="token"></interceptor-ref>
			<result name="success">/token/success.jsp</result>
			<result name="invalid.token">/token/invalid.jsp</result>
		</action>
	</package>
</struts>

struts-token.xml添加到struts.xml中

<include file="com/rk/strut/h_token/struts-token.xml"></include>

(3)前台表单页面add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>添加学生</title>
</head>
<body>
	<form action="${pageContext.request.contextPath }/rk/token/add" method="post">
		用户名:<input type="text" name="username"/><br/>
		密码:<input type="password" name="password"/><br/>
		<input type="submit" value="提交"/>
		<s:token></s:token>
	</form>
</body>
</html>



(4)错误处理页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>token无效</title>
</head>
<body>
	<s:actionerror/>
</body>
</html>

可以看一下<s:token>标签生成的html代码

4、补充

服务器端和客户端通过token(令牌)来进行验证:

(1)Browser向Tomcat服务器请求填写表单

(2)Tomcat服务器将带有token的表单返回给Browser

(3)浏览器端在提交时,将form和token一起发送到服务器

(4)Tomcat服务器对Browser进行验证

token拦截器定义在名为struts-default的package内。

struts-default.xml

<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>

org.apache.struts2.interceptor.TokenInterceptor

(1)举例

This interceptor can make sure that back buttons and double clicks don‘t cause un-intended side affects. For example, you can use this to prevent careless users who might double click on a "checkout" button at an online store.

(2)服务器端实现机制

This interceptor uses a fairly primitive technique for when an invalid token is found: it returns the result invalid.token【返回invalid.token】, which can be mapped in your action configuration. A more complex implementation, TokenSessionStoreInterceptor【更复杂的实现TokenSessionStoreInterceptor】, can provide much better logic for when invalid tokens are found.

(3)浏览器端必须使用token tag

To set a token in your form, you should use the token tag【在JSP的form中应该使用token tag】. This tag is required and must be used in the forms that submit to actions protected by this interceptor.

(4)注意

Any request that does not provide a token (using the token tag) will be processed as a request with an invalid token.

如果浏览器端不带有token信息,将被视为无效的token。

(5)示例代码

Example code:

 <action name="someAction" class="com.examples.SomeAction">
     <interceptor-ref name="token"/>
     <interceptor-ref name="basicStack"/>
     <result name="success">good_result.ftl</result>
 </action>
 <-- In this case, myMethod of the action class will not
        get checked for invalidity of token -->
 <action name="someAction" class="com.examples.SomeAction">
     <interceptor-ref name="token">
        <param name="excludeMethods">myMethod</param>
     </interceptor-ref name="token"/>
     <interceptor-ref name="basicStack"/>
     <result name="success">good_result.ftl</result>
 </action>
时间: 2024-10-12 13:49:49

Struts2系列:(13)防表单重复提交(token + 拦截器)的相关文章

防表单重复提交

防表单重复提交 1.令牌生成器 import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; import sun.misc.BASE64Encoder; public class TokenProccessor { /* *单例设计模式(保证类的对象在内存中只有一个) *1.把类的构造函数私有 *2.自己创建一个类的对象 *3.对外提供一个公

10-客户端防表单重复提交和服务器端session防表单重复提交

/****************************************************DoFormServlet********************************************************/ package session; import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import

【struts2】struts防止表单重复提交

一.概述 表单重复提交已经存在很久了,也有很多讨论.防止表单重复提交主要是防止"服务器处理慢时的页面刷新",以及浏览器后退后再次提交,甚至是点击提交按钮的时候手快点了很多次. 常用的JS将提交按钮设置成disabled,这种防止不了页面刷新,重定向防止不了浏览器后退后重复提交,两者结合也没用. struts2采用的是页面hidden+session来实现防止重复提交,通过拦截器token或或tokenSession来说hi线,其思想很简单,本文主要是讨论实现代码中涉及的细节. 二.原理

Struts2(八)之UI标签和防止表单重复提交

一.UI标签 1.1.struts2中UI标签的优势 自动的数据回显和错误提示功能 自带的简单样式和排版 1.2.UI案例 结果: 1.3.UI标签的主题 1.3.1.struts2中默认的主题 默认主题的名称是XHTML,都是在struts的默认属性文件中定义着:default.properties 默认模板存放位置: 1.3.2.更改默认主题 1.更改表单某个元素的默认主题:使用的是表单元素的theme属性. 2.更改表单所有主题:使用的是form标签的theme属性. 3.更改全站所有表单

关于struts2防止表单重复提交

struts2防表单重复提交有两种方式. 其一是action的重定向,跳转时设置type为从一个action跳转到另一个action或者另一个页面, 使用户提交后,所停留的位置,不是当前处理数据的Action,这样用户再刷新时,就不会再次执行这个Action了, 就会避免表单重复提交的问题了. 其二就是session令牌的方式(token) 处理也很方便,只需要在所提交的表单上加一个struts2标签  <s:token> 注意在该页面需要导入  <%@taglib prefix=&qu

struts2之防止表单重复提交

struts.xml配置文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts

【Struts2】防止表单重复提交

一.概述 二.Struts2中解决方案 三.实现步骤 一.概述 regist.jsp----->RegistServlet 表单重复提交 危害: 刷票. 重复注册.带来服务器访问压力(拒绝服务) 解决方案: 在页面上生成一个令牌(就是一个随机字符串),将其存储到session中,并在表单中携带. 在服务器端,获取数据时,也将令牌获取,将它与session中存储的token对比,没问题,将session中令牌删除. 二.Struts2中解决方案 struts2中怎样解决表单重复提交: 在strut

Session应用之---防止表单重复提交

Session应用之---防止表单重复提交 客户端防止(采用JavaScript阻止方式): PS:防得住君子,防不了小人 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>防表单重复提交</title> <meta http-equiv="keywords" content=&qu

12-struts2防止表单重复提交

防止表单重复提交 问题:什么是表单重复提交? regist.jsp----->RegistServlet 表单重复提交 危害: 刷票. 重复注册.带来服务器访问压力(拒绝服务) 解决方案: 在页面上生成一个令牌(就是一个随机字符串),将其存储到session中,并在表单中携带. 在服务器端,获取数据时,也将令牌获取,将它与session中存储的token对比,没问题, 将session中令牌删除. struts2中怎样解决表单重复提交: 在struts2中解决表单重复提交,可以使用它定义的一个i