zoukankan      html  css  js  c++  java
  • 关于struts2防止表单重复提交

    struts2防表单重复提交有两种方式。

    其一是action的重定向,跳转时设置type为从一个action跳转到另一个action或者另一个页面,

    使用户提交后,所停留的位置,不是当前处理数据的Action,这样用户再刷新时,就不会再次执行这个Action了,

    就会避免表单重复提交的问题了。

    其二就是session令牌的方式(token)

    处理也很方便,只需要在所提交的表单上加一个struts2标签  <s:token>

    注意在该页面需要导入  <%@taglib prefix="s" uri="/struts-tags"%>

    这样,当浏览器第一次访问这个带有<s:token>标签的页面时,在服务器中,解析<s:token>标签的类(TokenTag.class),

    会生成一个随机的字符串(这个字符串,查看网页的源代码可以看到),并且发送给客户端的浏览器,同时,在服务器中,

    会把这个随机字符串保存到用户的session对象中。

    当第一次提交表单时,在服务器中,会比较客户端和服务器中分别保存的这个随机字符串,因为是第一次提交,

    所以这两个字符串相等,然后进行正常的业务处理。第一次提交后,在服务器中的session中保存的这个随机字符串,

    会改变为其他的随机值,注意,这是很重要的一步!此时,地址栏停留在处理用户提交数据的Action中,

    客户端中保存的随机字符串没有改变,若是刷新页面,即重复提交,服务器再进行两个字符串的比较,

    会不相等,就会跳转到name为invalid.token的结果页面中,这样就会防止表单重复提交了。

    贴上示例代码

    struts_regist.jsp

     1 <%@ taglib prefix="s" uri="/struts-tags" %>
     2 <%--
     3   Created by IntelliJ IDEA.
     4   User: leslie
     5   Date: 17-12-2
     6   Time: 上午10:46
     7   To change this template use File | Settings | File Templates.
     8 --%>
     9 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    10 <html>
    11 <head>
    12     <title>注册</title>
    13 </head>
    14 <body>
    15     <form action="${pageContext.request.contextPath}/struts_regist" method="post">
    16         <s:token />
    17         用户名:<input type="text" name="name"><br>
    18         密&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"><br>
    19         <input type="submit" value="注册">
    20     </form>
    21 </body>
    22 </html>

    struts.xml

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE struts PUBLIC
     3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
     4     "http://struts.apache.org/dtds/struts-2.3.dtd">
     5 
     6 <struts>
     7     <package name="default" namespace="/" extends="struts-default">
     8         <action name="regist" class="cn.itcast.action.RegistAction">
     9             <result name="invalid.token">/token.jsp</result>
    10             <interceptor-ref name="token" />
    11             <interceptor-ref name="defaultStack" />
    12         </action>
    13     </package>
    14 </struts>

    token.jsp

     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <%@taglib prefix="s" uri="/struts-tags"%>
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5   <head>
     6     <title>My JSP 'index.jsp' starting page</title>
     7   </head>
     8 
     9   <body>
    10     <s:actionerror/>
    11   </body>
    12 </html>

    RegistAction

     1 package com.emuii.action;
     2 
     3 import com.opensymphony.xwork2.ActionSupport;
     4 import org.apache.struts2.ServletActionContext;
     5 
     6 public class RegistAction extends ActionSupport {
     7 
     8     @Override
     9     public String execute() throws Exception {
    10 
    11        String name = ServletActionContext.getRequest().getParameter("name");
    12        String password = ServletActionContext.getRequest().getParameter("password");
    13 
    14        System.out.println(name+":"+password+"已注册");
    15 
    16        return null;
    17     }
    18 }

    如果想要自定义错误信息,只需在action同一目录下创建一个 ----类名.properties配置文件即可

    RegistAction.properties

    1 struts.messages.invalid.token=u60A8u5DF2u7ECFu91CDu590Du63D0u4EA4u8868u5355uFF0Cu8BF7u5237u65B0u540Eu91CDu8BD5

    另:对于只有一个action来说,通配符跳转的方式第一种防表单提交无效的,虽然重定向之后的jsp页面不一样。

    如果需要对特定的方法进行防表单提交这样:

    1 <action name="someAction" class="com.examples.SomeAction">
    2      <interceptor-ref name="token">
    3         <param name="includeMethods">myMethod</param>
    4      </interceptor-ref name="token"/>
    5      <interceptor-ref name="basicStack"/>
    6      <result name="success">good_result.ftl</result>
    7  </action>

    <param name="includeMethod">xx</param>表示只拦截xx方法

    <param name="excludeMethod">xx</param>表示拦截xx方法之外的方法

    另:WARN [org.apache.struts2.util.TokenHelper] - Could not find token name in params.出现这个问题,

    也有可能是你没对指定方法进行拦截,当然情况不一定非是这种的,只是因为我的项目问题才导致这个问题的。

  • 相关阅读:
    eclipse版本、代号
    eclipse中jdk及编译器版本问题
    改变cmd命令行颜色
    mysql-installer-community-8.0.12.0的安装
    算法简介
    Java--将数据以文本形式导出
    安装MySQL
    网络配置
    电脑拷软件到其他设备
    探针设备
  • 原文地址:https://www.cnblogs.com/lesliehe/p/7989560.html
Copyright © 2011-2022 走看看