防止表达重复提交

防止表达重复提交

  • 问题:什么是表单重复提交?

    • 当在注册或者登陆遇到网络卡顿或者页面不能正常刷新时,我们大多数人都会进行对此的刷新操作;
    • 如果不进行表单重复提交的处理会带来很大的危害
    • 表单重复提交 危害: 刷票、 重复注册、带来服务器访问压力(拒绝服务)
  • 解决方案:

    • 在页面上生成一个令牌(就是一个随机字符串UUID),将其存储到session中,并在表单中携带.
    • 在服务器端,获取数据时,也将令牌获取,将它与session中存储的token对比,没问题,
    • 将session中令牌删除。

Servelt的防止表单重复提交

在Register.jsp页面随机生成令牌,并将其带到服务器端

Register.jsp

<body>
<!-- 生成随机的令牌 -->
<%
	String token = UUID.randomUUID().toString(); 
	session.setAttribute("token", token);
%>
<form action="${pageContext.request.contextPath }/register" method="get" >
	<input type="hidden" name="token" value="<%=token%>" />
	username:<input type="text"  name="username" /><br>
	password:<input type="password"  name="password" /><br>
	<input type="submit" value="注册"/>
</form>
	
</html>

RegisterServlet.java服务器端进行处理:

@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 取出参数中的令牌和在session中的进行对比
		String token = request.getParameter("token");
		String _token = (String) request.getSession().getAttribute("token");
		// 移除令牌
		request.getSession().removeAttribute("token");
		if (token.equals(_token)) {
			System.out.println("将" + username + " 与" + password + "存储到数据库中,完成注册");
		} else {
			response.getWriter().write("不允许表单重复提交");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

Struts2的表单重复提交

struts2中怎样解决表单重复提交:

  • 在struts2中解决表单重复提交,可以使用它定义的一个interceptor。

    <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
    
  • 步骤:

    1. 在页面上需要使用一个token tag

      在表单中添加一个标签 <s:token/>

      就会在页面上生成一个令牌,并存在于表单中。

    2. 需要在action中引入token拦截器

      同时引入默认的拦截器栈(defaultStack)或者最基本的拦截器栈(basicStack)

      <interceptor-ref name=“token”/>

    3. 在重复提交时会报错,我们需要对错误进行配置和显示

      • 在struts.xml中配置invalid.token结果视图
      	<!-- 可以选择将其重返注册页面 -->
      <result name="invalid.token">/Struts2_Register.jsp</result>
      
      • 在jsp页面使用标签进行错误的显示:

        <s:actionerror/>

    4. 在显示的错误信息时将其国际化

      在struts2-core-2.3.33.jar的org.apache.struts2包下的struts-messages.properties文件中有一个常量struts.messages.invalid.token是用来显示错误的

      在同action下创建同名的配置文件ActionClassName.properties

      struts.messages.invalid.token=禁止表单重复提交
      
  • Struts2_Register.jsp页面:

    <%@page import="java.util.UUID"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@taglib prefix="s" uri="/struts-tags" %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <s:actionerror/>
    	<form action="${pageContext.request.contextPath }/register"	method="get">
    		<s:token/>
    		username:<input type="text" name="username" /><br> 
    		password:<input	type="password" name="password" /><br> 
    		<input type="submit" value="注册" />
    	</form>
    
    </html>
    

    RegisterAction.java

    package com.syj.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class RegisterAction 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;
    	}
    
    	@Override
    	public String execute() throws Exception {
    		System.out.println("将" + username + " 与" + password + "存储到数据库中,完成注册");
    		return null;
    	}
    }
    
    

    struts.xml配置

    <struts>
    	<package name="p1"	extends="struts-default" namespace="/">
    		<action	name="register"	class="com.syj.action.RegisterAction">
    			<interceptor-ref name="token" />
    			<interceptor-ref name="defaultStack" />
    			<!-- 可以选择将其重返注册页面 -->
    			<result name="invalid.token">/Struts2_Register.jsp</result>
    		</action>
    	</package>
    </struts>
    

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值