• Struts2第十三篇【防止表单重复提交】


    回顾防止表单重复提交

    当我们学习Session的时候已经通过Session来编写了一个防止表单重复提交的小程序了,我们来回顾一下我们当时是怎么做的:

    • 在Servlet上生成独一无二的token,保存在Session域中,并交给JSP页面
    • JSP页面在提交表单数据的时候,把token放在隐藏域中…一起带过去给Servlet
    • Servlet判断用户有没有带token值过来,判断token的值是否和Session的相匹配
    • 如果用户是第一次提交的话,那么就允许用户的请求,接着就把保存在Session中的token值去除
    • 等用户想要再次提交的时候,Servlet发现Session中并没有token了,所以不搭理用户的请求

    我们以前写表达重复提交就花了这么几个步骤…如果有兴趣的同学可以看一下以前的实现思路:http://blog.csdn.net/hon_3y/article/details/54799494#t11


    Struts2防止表单重复提交

    Struts2是简化我们的开发的,表单重复提交也是一件非常常用的功能…Struts2也为我们实现了…当然啦,也是通过拦截器来实现

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

    它的实现原理和我们以前写的思路几乎一致…它不需要另外写一个组件来生成token值,struts2标签就有这么一个功能…因此是十分方便的

    这里写图片描述

    为了熟悉一下Struts2,我们也使用Struts2来编写一下上图的程序

    编写DAO

    
    package zhongfucheng.dao;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import zhongfucheng.entity.User;
    import zhongfucheng.utils.Utils2DB;
    
    import java.sql.SQLException;
    import java.util.List;
    
    /**
     * Created by ozc on 2017/5/3.
     */
    public class UserDao {
    
        public void add(User user) {
            try {
    
                String sql = "INSERT INTO user(id,username,cellphone,password,address) VALUES (?,?,?,?,?)";
                QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
    
                queryRunner.update(sql, new Object[]{user.getId(), user.getUsername(), user.getCellphone(), user.getPassword(),user.getAddress()});
    
            } catch (SQLException e) {
                new RuntimeException("登陆失败了!");
            }
        }
    
        public User findUser(String id) {
            try {
                String sql = "SELECT * FROM user WHERE id=?";
                QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
    
                return (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{id});
    
            } catch (SQLException e) {
                new RuntimeException("登陆失败了!");
            }
            return null;
        }
    
        public List<User> getAll() {
    
            try {
                String sql = "SELECT * FROM user";
                QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
                return (List<User>) queryRunner.query(sql, new BeanListHandler(User.class));
            } catch (SQLException e) {
                new RuntimeException("登陆失败了!");
            }
            return null;
        }
        public void  updateUser(User user) {
    
            try {
                String sql = "UPDATE user SET username=?,password=?,cellphone=? WHERE id=?";
                QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
    
                queryRunner.update(sql, new Object[]{user.getUsername(), user.getPassword(), user.getCellphone(), user.getId()});
            } catch (SQLException e) {
                new RuntimeException("登陆失败了!");
            }
        }
    
    }
    

    编写service

    
    package zhongfucheng.service;
    
    import zhongfucheng.dao.UserDao;
    import zhongfucheng.entity.User;
    import zhongfucheng.utils.WebUtils;
    
    import java.util.List;
    
    /**
     * Created by ozc on 2017/5/3.
     */
    public class Service {
    
        UserDao userDao = new UserDao();
    
        public void add(User user) {
    
    
            //手动设置id,因为在数据库表我没使用自动增长id
            user.setId(WebUtils.makeId());
    
            //这是以前的表,规定要address,只能手动设置了
            user.setAddress("广州");
            userDao.add(user);
    
        }
    
        public User findUser(String id) {
    
            return userDao.findUser(id);
    
        }
    
        public List<User> getAll() {
    
            return userDao.getAll();
    
        }
        public void  updateUser(User user) {
    
    
            userDao.updateUser(user);
    
        }
    }
    

    开发步骤

    • 编写添加用户JSP
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="s" uri="/struts-tags" %>
    <html>
    <head>
    </head>
    <body>
    
    <form action="${pageContext.request.contextPath}/user_register" method="post">
        <table border="1">
    
            <tr>
                <td>用户名:<input type="text" name="username"></td>
            </tr>
            <tr>
                <td> 密码:<input type="password" name="password"></td>
            </tr>
            <tr>
                <td>电话:<input type="text" name="cellphone"></td>
            </tr>
            <tr>
                <td><input type="submit" value="提交"></td>
            </tr>
        </table>
    </form>
    
    
    </body>
    </html>
    
    • 使用了模型驱动封装数据,添加用户
    
    
        //这里一定要实例化
        User user = new User();
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        @Override
        public User getModel() {
            return user;
        }
    
    
        /*******调用service********/
        Service service = new Service();
    
        public String register() throws Exception {
    
            service.add(user);
    
    
            //注册成功,就跳转到list()方法,list方法就跳转到查看所有用户页面了!
            return list();
        }
    • 列出全部的用户数据,提供修改功能,需要把id传递过去,明确修改的是哪一个用户
    
    <%--
      Created by IntelliJ IDEA.
      User: ozc
      Date: 2017/5/2
      Time: 18:24
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    <%@ taglib prefix="s" uri="/struts-tags" %>
    <html>
    <head>
        <title>列出下载页面</title>
    </head>
    <body>
    <table border="1" align="center">
        <tr>
            <td>用户id</td>
            <td>用户姓名</td>
            <td>用户密码</td>
            <td>用户电话</td>
            <td>操作</td>
        </tr>
    
        <s:if test="#request.users!=null">
            <c:forEach items="${users}" var="user">
                <tr>
                    <td>${user.id}</td>
                    <td>${user.username}</td>
                    <td>${user.password}</td>
                    <td>${user.cellphone}</td>
                    <td><a href="${pageContext.request.contextPath}/user_updatePage?id=${user.id}">修改</a></td>
                </tr>
            </c:forEach>
        </s:if>
    </table>
    
    
    </body>
    </html>
    
    • Action得到web带过来的id,找到对象,添加到值栈中(数据回显)
    
        public String updatePage() throws Exception {
    
            //得到用户带过来的id,根据id查找对象
           User user222 = service.findUser(user.getId());
    
            ActionContext.getContext().getValueStack().push(user222);
    
            return "updatePage";
        }
    • 修改用户的JSP页面,使用Struts2提供的回显技术,并把id通过隐藏域带过去给Action..最终是通过id来修改用户的数据
    
    <form action="${pageContext.request.contextPath}/user_update">
        <table border="1">
    
            <tr>
                <td>用户名<s:textfield name="username"/></td>
            </tr>
            <tr>
                <td>密码 <s:textfield name="password" /></td>
            </tr>
            <tr>
                <td>电话<s:textfield name="cellphone"/></td>
            </tr>
            <s:hidden name="id"/>
    
            <tr>
                <td><input type="submit" value="修改"></td>
            </tr>
        </table>
    </form>
    

    效果

    这里写图片描述


    防止表单重复提交

    上面我们已经完成了大部分的功能了,但当我们如果提交之后,再刷新页面,那么表单的数据就会重复提交…我们使用Struts2我们提供的防止表单重复提交的功能把!

    这里写图片描述

    在需要提交的表单上使用token标签

    
    <table border="1">
            <s:token></s:token>
            <tr>
                <td>用户名:<input type="text" name="username"></td>
            </tr>
            <tr>
                <td> 密码:<input type="password" name="password"></td>
            </tr>
            <tr>
                <td>电话:<input type="text" name="cellphone"></td>
            </tr>
            <tr>
                <td><input type="submit" value="提交"></td>
            </tr>
        </table>

    在struts配置文件中配置拦截器

    token拦截器默认是不会启动的,也就是说:需要我们手动配置

    当我们配置拦截器的时候,Struts2默认的拦截器是不会执行的,所以要把Struts2默认的拦截器也写上

    
    <?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>
        <constant name="struts.ui.theme" value="simple"/>
        <package name="xxx" extends="struts-default">
    
    
    
            <action name="user_*" class="zhongfucheng.action.UserAction" method="{1}">
    
                <interceptor-ref name="defaultStack"/>
    
                <interceptor-ref name="token">
                    <!-- 要拦截的方法! -->
                    <param name="includeMethods">register</param>
                </interceptor-ref>
    
                <!--如果是list,那么就跳转到list的JSP页面-->
                <result name="list"> /list.jsp</result>
    
                <!--请求跳转到修改页面-->
                <result name="updatePage">/update.jsp</result>
    
                <!--如果校验成功,跳转到login.jsp页面回显-->
                <result name="success">/login.jsp</result>
    
                <result name="redirectList" type="redirect">/user_list</result>
            </action>
        </package>
    
        <include file="config.xml"/>
    
    </struts>
    
    • 当我们重复提交的时候,它会报错,因此,如果它报错了,我们就跳转到register页面把

    这里写图片描述

    测试

    这里写图片描述

  • 相关阅读:
    Oracle数据库容灾备份技术探讨
    asp.net 生成、解析条形码和二维码
    推荐一些C#相关的网站、资源和书籍
    内部集群的 DNS server 搭建
    Nginx 负载均衡
    webpack技巧:动态批量加载文件
    Mock.js使用
    @vue/cli 项目编译重复命中缓存问题解析
    用React hooks实现TDD
    从 React 切换到 Vue.js
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7202976.html
Copyright © 2020-2023  润新知