回顾防止表单重复提交
当我们学习Session的时候已经通过Session来编写了一个防止表单重复提交的小程序了,我们来回顾一下我们当时是怎么做的:
在Servlet上生成独一无二的token,保存在Session域中,并交给JSP页面JSP页面在提交表单数据的时候,把token放在隐藏域中…一起带过去给ServletServlet判断用户有没有带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) {
user.setId(WebUtils.makeId());
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);
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 {
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>
<result name="list"> /list.jsp
</result>
<result name="updatePage">/update.jsp
</result>
<result name="success">/login.jsp
</result>
<result name="redirectList" type="redirect">/user_list
</result>
</action>
</package>
<include file="config.xml"/>
</struts>
当我们重复提交的时候,它会报错,因此,如果它报错了,我们就跳转到register页面把
测试