拦截器Interceptor…..拦截器是Struts的概念,它与过滤器是类似的…可以近似于看作是过滤器

前面在介绍Struts的时候已经讲解过了,Struts为我们实现了很多的功能,比如数据自动封装阿..文件上传功能阿….Struts为我们提供的这些功能都是通过拦截器完成的……

  • 数据自动封装通过<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>这个拦截器。
  • 文件上传通过<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>这个拦截器

拦截器的设计就是基于组件设计的应用

在开始讲解Struts的时候已经说明过了struts-default.xml这个文件,它定义了Struts的所有拦截器。因为我们在启动服务器的时候会自动装载这个文件,因此我们才可以在Action中使用到Struts为我们提供的功能【数据自动封装…文件上传】

在struts-default.xml中定义的拦截器就有32个之多,Struts2为了方便我们对拦截器的引用,提供了拦截器栈的定义。

  1. <interceptor-stack name="defaultStack">
  2. <interceptor-ref name="exception"/>
  3. <interceptor-ref name="alias"/>
  4. <interceptor-ref name="servletConfig"/>
  5. <interceptor-ref name="i18n"/>
  6. <interceptor-ref name="prepare"/>
  7. <interceptor-ref name="chain"/>
  8. <interceptor-ref name="scopedModelDriven"/>
  9. <interceptor-ref name="modelDriven"/>
  10. <interceptor-ref name="fileUpload"/>
  11. <interceptor-ref name="checkbox"/>
  12. <interceptor-ref name="multiselect"/>
  13. <interceptor-ref name="staticParams"/>
  14. <interceptor-ref name="actionMappingParams"/>
  15. <interceptor-ref name="params">
  16. <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
  17. </interceptor-ref>
  18. <interceptor-ref name="conversionError"/>
  19. <interceptor-ref name="validation">
  20. <param name="excludeMethods">input,back,cancel,browse</param>
  21. </interceptor-ref>
  22. <interceptor-ref name="workflow">
  23. <param name="excludeMethods">input,back,cancel,browse</param>
  24. </interceptor-ref>
  25. <interceptor-ref name="debugging"/>
  26. </interceptor-stack>

也就是说:当我们要引用多个拦截器的时候,只要把拦截器都放在栈里头,在外边引用拦截器即可!

值得注意的是:Struts2默认执行的是默认拦截器栈,一旦用户有指定执行哪些拦截器,那么默认的拦截器栈就不会被执行!


Struts2允许我们自定义拦截器,这就使我们能够更加灵活地操作Struts2这个框架了!

Struts2提供了Interceptor这个拦截器接口,只要我们实现这个接口,那么这就算是自定义开发拦截器了。

当然啦,大部分时候,我们定义拦截器都是继承AbstractInterceptor这个类….为了学习拦截器的内容,下面就实现Interceptor这个接口了。

  • 当实现该接口时,有3个需要我们实现的方法:
  1. public class MyInterceptor implements Interceptor {
  2. @Override
  3. public void destroy() {
  4. }
  5. @Override
  6. public void init() {
  7. }
  8. @Override
  9. public String intercept(ActionInvocation actionInvocation) throws Exception {
  10. return null;
  11. }
  12. }

init()和destory()都是和拦截器执行顺序有关的方法,我们现在先不理会….首先来讲解intercept这个方法

  1. /**
  2. * @param actionInvocation 拦截器的执行状态
  3. */
  4. @Override
  5. public String intercept(ActionInvocation actionInvocation) throws Exception {
  6. //调用invoke()方法,代表着放行执行下一个拦截器,如果没有拦截器了,那么就执行Action的业务代码
  7. actionInvocation.invoke();
  8. return null;
  9. }

这很容易就能让我们想起在学习过滤器中的doFilter()方法,其实是差不多的!


像Struts默认的拦截器一样,我们自定义的拦截器是需要我们在struts中配置的。

由于我们配置了自定义拦截器,那么struts默认的拦截器栈是不会执行的。如果我们想要使用默认拦截器栈的功能,就必须把它配置在我们自定义的栈中!

  1. <package name="xxx" extends="struts-default" >
  2. <interceptors>
  3. <!--配置用户自定义的拦截器-->
  4. <interceptor name="MyInterceptor" class="TestAction"/>
  5. <!--自定义拦截器栈,我们配置了自定义的拦截器,默认的拦截器栈就不会被执行,因此,想要使用默认的拦截器功能,就要配置进来-->
  6. <interceptor-stack name="mystack">
  7. <!--引用默认的拦截器栈,一定要放在第一行-->
  8. <interceptor-ref name="defalutStack"/>
  9. <!--引用自定义的拦截器-->
  10. <interceptor-ref name="MyInterceptor"/>
  11. </interceptor-stack>
  12. </interceptors>
  13. <!--上面配置了拦截器栈,但是没有被执行...下面配置执行拦截器-->
  14. <default-interceptor-ref name="mystack"/>
  15. <action name="TestAction" class="TestAction" method="execute">
  16. <result name="success">/index.jsp</result>
  17. </action>
  18. </package>

我们来观察拦截器和Action类的执行顺序…只要在对应的方法上向控制台输出就行了!

  • 拦截器
  1. public class MyInterceptor implements Interceptor {
  2. @Override
  3. public void destroy() {
  4. System.out.println("我是拦截器的销毁方法");
  5. }
  6. @Override
  7. public void init() {
  8. System.out.println("我是拦截器的初始化方法");
  9. }
  10. /**
  11. * @param actionInvocation 拦截器的执行状态
  12. */
  13. @Override
  14. public String intercept(ActionInvocation actionInvocation) throws Exception {
  15. System.out.println("我是拦截器的拦截方法");
  16. //调用invoke()方法,代表着放行执行下一个拦截器,如果没有拦截器了,那么就执行Action的业务代码
  17. //可看成是过滤器的doFilter()方法
  18. actionInvocation.invoke();
  19. return null;
  20. }
  21. }
  • Action类
  1. public class TestAction extends ActionSupport {
  2. public TestAction() {
  3. System.out.println("我是Action类,我被初始化了!");
  4. }
  5. @Override
  6. public String execute() throws Exception {
  7. System.out.println("我是Action类的执行方法");
  8. return null;
  9. }
  10. }

这里写图片描述

从效果图我们可以看出,他们的执行顺序是这样的:

  • 当服务器开启的时候,会执行拦截器的init()方法
  • 当访问Action时,Action实例被创建
  • 创建完Action实例,会调用拦截器的interceptor()方法
  • 最后,执行Action的execute()方法

其实很好理解,之前我们使用Struts为我们提供数据自动封装功能的时候,是这样子的:

  • 服务器启动,加载配置文件的信息
  • 初始化默认的拦截器栈
  • 当用户访问Action时,创建Action的实例。拿到Action具体的信息【成员变量、setter和getter】
  • 执行拦截器具体的内容,根据Action具体的信息,把web端的数据封装到Action上
  • 最后在execute()就可以得到封装后的数据了!

这里写图片描述


需求:当用户登陆成功,跳转到显示用户的JSP页面中。当用户登陆失败,重新返回登陆界面。如果用户直接访问显示用户的JSP页面,那么返回到登陆界面

这里写图片描述

实现这个需求,我们可以使用过滤器的。只要获取用户的请求URL,再判断URL是不是为list.jsp,如果是,我们返回到登陆的界面就好了。

现在,为了对拦截器的理解,我们使用拦截器去完成这个功能!


  • 导入我们c3p0.xml文件
  • 导入c3p0开发包
  • 导入mysql开发包
  • 写数据库连接池工具类
  • dbUtils开发包
  • 8个struts2需要用到的开发包

这里写图片描述

  • 创建数据库表,导入数据

这里写图片描述

  1. package zhongfucheng.entity;
  2. /**
  3. * Created by ozc on 2017/5/3.
  4. */
  5. public class User {
  6. private String id ;
  7. private String username;
  8. private String cellphone;
  9. private String email;
  10. private String password;
  11. public String getId() {
  12. return id;
  13. }
  14. public void setId(String id) {
  15. this.id = id;
  16. }
  17. public String getUsername() {
  18. return username;
  19. }
  20. public void setUsername(String username) {
  21. this.username = username;
  22. }
  23. public String getCellphone() {
  24. return cellphone;
  25. }
  26. public void setCellphone(String cellphone) {
  27. this.cellphone = cellphone;
  28. }
  29. public String getEmail() {
  30. return email;
  31. }
  32. public void setEmail(String email) {
  33. this.email = email;
  34. }
  35. public String getPassword() {
  36. return password;
  37. }
  38. public void setPassword(String password) {
  39. this.password = password;
  40. }
  41. }
  1. package zhongfucheng.dao;
  2. import org.apache.commons.dbutils.QueryRunner;
  3. import org.apache.commons.dbutils.handlers.BeanHandler;
  4. import org.apache.commons.dbutils.handlers.BeanListHandler;
  5. import zhongfucheng.entity.User;
  6. import zhongfucheng.utils.Utils2DB;
  7. import java.sql.SQLException;
  8. import java.util.List;
  9. /**
  10. * Created by ozc on 2017/5/3.
  11. */
  12. public class UserDao {
  13. public User login(User user) {
  14. try {
  15. String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
  16. QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
  17. return (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{user.getUsername(), user.getPassword()});
  18. } catch (SQLException e) {
  19. new RuntimeException("登陆失败了!");
  20. }
  21. return null;
  22. }
  23. public List<User> getAll() {
  24. try {
  25. String sql = "SELECT * FROM user";
  26. QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
  27. return (List<User>) queryRunner.query(sql, new BeanListHandler(User.class));
  28. } catch (SQLException e) {
  29. new RuntimeException("登陆失败了!");
  30. }
  31. return null;
  32. }
  33. }
  1. public class Service {
  2. UserDao userDao = new UserDao();
  3. public User login(User user) {
  4. return userDao.login(user);
  5. }
  6. public List<User> getAll() {
  7. return userDao.getAll();
  8. }
  9. }
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>登陆页面</title>
  5. </head>
  6. <body>
  7. <form action="${pageContext.request.contextPath}/user_login" method="post">
  8. <input type="text" name="username"><br>
  9. <input type="password" name="password"><br>
  10. <input type="submit" value="登陆"><br>
  11. </form>
  12. </body>
  13. </html>
  1. package zhongfucheng.action;
  2. import com.opensymphony.xwork2.ActionContext;
  3. import zhongfucheng.entity.User;
  4. import zhongfucheng.service.Service;
  5. import java.util.List;
  6. import java.util.Map;
  7. /**
  8. * Created by ozc on 2017/5/3.
  9. */
  10. public class UserAction {
  11. /****************1.封装数据********************/
  12. private User user;
  13. public User getUser() {
  14. return user;
  15. }
  16. public void setUser(User user) {
  17. this.user = user;
  18. }
  19. /***************2.调用Service*******************/
  20. Service service = new Service();
  21. //登陆
  22. public String login() {
  23. User user = service.login(this.user);
  24. if (user == null) {
  25. return "input";
  26. } else {
  27. //将user的信息存到Session域对象中
  28. Map<String, Object> session = ActionContext.getContext().getSession();
  29. session.put("user", user);
  30. //登陆成功
  31. return "login";
  32. }
  33. }
  34. //查看user信息
  35. public String list() {
  36. //拿到所有用户的信息
  37. List<User> users = service.getAll();
  38. //存到request域对象中
  39. Map<String, Object> request = ActionContext.getContext().getContextMap();
  40. request.put("users", users);
  41. return "list";
  42. }
  43. }
  1. <package name="xxx" extends="struts-default" >
  2. <action name="user_*" class="zhongfucheng.action.UserAction" method="{1}" >
  3. <!--如果登陆成功,重定向到Action中,执行list业务方法-->
  4. <result name="login" type="redirectAction">user_list</result>
  5. <!--如果是list,那么跳转到list.jsp页面-->
  6. <result name="list" >/WEB-INF/list.jsp</result>
  7. </action>
  8. </package>

到目前为止,我们登陆或者不登陆都可以得到用户的具体信息….这是不合理的

我们想要的效果是:只有用户正在调用login方法,或者该用户已经登陆了,才可以查看具体的用户信息

这里写图片描述

因此,我们们要拦截它们,只有用户调用的是login方法时或者已经登陆的情况下,才能跳转到对应的显示页面


  1. package zhongfucheng;
  2. import com.opensymphony.xwork2.ActionContext;
  3. import com.opensymphony.xwork2.ActionInvocation;
  4. import com.opensymphony.xwork2.ActionProxy;
  5. import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
  6. /**
  7. * Created by ozc on 2017/5/3.
  8. */
  9. public class Interceptor extends AbstractInterceptor{
  10. @Override
  11. public String intercept(ActionInvocation actionInvocation) throws Exception {
  12. //得到正在执行的代理对象
  13. ActionProxy proxy = actionInvocation.getProxy();
  14. //通过代理对象得到正在执行的方法
  15. String method = proxy.getMethod();
  16. //如果方法的名字不是login,那么就让他们返回到login页面上
  17. if (!method.equals("login")) {
  18. //查看用户是否登陆了
  19. Object user = ActionContext.getContext().getSession().get("user");
  20. //如果没有登陆,回到login页面
  21. if (user == null) {
  22. return "input";
  23. } else {
  24. //登陆了,那么就让它访问具体的用户信息页面
  25. return actionInvocation.invoke();
  26. }
  27. } else {
  28. //如果是访问login方法,那么就让它执行
  29. return actionInvocation.invoke();
  30. }
  31. }
  32. }
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
  4. "http://struts.apache.org/dtds/struts-2.0.dtd">
  5. <struts>
  6. <package name="xxx" extends="struts-default">
  7. <interceptors>
  8. <!--配置自定义的拦截器-->
  9. <interceptor name="Interceptor1" class="zhongfucheng.Interceptor"/>
  10. <!--配置拦截器栈,把默认的拦截器栈都加载自定义的拦截器栈中-->
  11. <interceptor-stack name="myStack">
  12. <interceptor-ref name="Interceptor1"/>
  13. <interceptor-ref name="defaultStack"/>
  14. </interceptor-stack>
  15. </interceptors>
  16. <!--让Struts执行拦截器-->
  17. <!--【执行拦截器:第一种写法: 当前包下所有的acntion都执行myStack栈】-->
  18. <default-interceptor-ref name="myStack"></default-interceptor-ref>
  19. <!--第二种写法: 只是在这一个Action中执行myStack栈
  20. <interceptor-ref name="defaultStackt"></interceptor-ref>
  21. <interceptor-ref name="loginCheck"></interceptor-ref>
  22. -->
  23. <!-- 第三种写法:执行用户栈(与第二种写法一样, 只在当前aciton中执行自定义栈) -->
  24. <!-- <interceptor-ref name="myStack"></interceptor-ref>-->
  25. <action name="user_*" class="zhongfucheng.action.UserAction" method="{1}">
  26. <!--如果登陆成功,重定向到Action中,执行list业务方法-->
  27. <result name="login" type="redirectAction">user_list</result>
  28. <!--如果是list,那么跳转到list.jsp页面-->
  29. <result name="list">/WEB-INF/list.jsp</result>
  30. <!--如果是直接访问Action或者没有用户登陆,返回login页面-->
  31. <result name="input">/login.jsp</result>
  32. </action>
  33. </package>
  34. </struts>

只有当用户登陆了才能查看用户具体信息,直接访问Action会跳转回

这里写图片描述


Struts2自带了计时拦截器,也就是用来统计每个Action执行的时间

如果页面执行得太慢了,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也为我们实现了…当然啦,也是通过拦截器来实现

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

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

这里写图片描述

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

  1. package zhongfucheng.dao;
  2. import org.apache.commons.dbutils.QueryRunner;
  3. import org.apache.commons.dbutils.handlers.BeanHandler;
  4. import org.apache.commons.dbutils.handlers.BeanListHandler;
  5. import zhongfucheng.entity.User;
  6. import zhongfucheng.utils.Utils2DB;
  7. import java.sql.SQLException;
  8. import java.util.List;
  9. /**
  10. * Created by ozc on 2017/5/3.
  11. */
  12. public class UserDao {
  13. public void add(User user) {
  14. try {
  15. String sql = "INSERT INTO user(id,username,cellphone,password,address) VALUES (?,?,?,?,?)";
  16. QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
  17. queryRunner.update(sql, new Object[]{user.getId(), user.getUsername(), user.getCellphone(), user.getPassword(),user.getAddress()});
  18. } catch (SQLException e) {
  19. new RuntimeException("登陆失败了!");
  20. }
  21. }
  22. public User findUser(String id) {
  23. try {
  24. String sql = "SELECT * FROM user WHERE id=?";
  25. QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
  26. return (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{id});
  27. } catch (SQLException e) {
  28. new RuntimeException("登陆失败了!");
  29. }
  30. return null;
  31. }
  32. public List<User> getAll() {
  33. try {
  34. String sql = "SELECT * FROM user";
  35. QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
  36. return (List<User>) queryRunner.query(sql, new BeanListHandler(User.class));
  37. } catch (SQLException e) {
  38. new RuntimeException("登陆失败了!");
  39. }
  40. return null;
  41. }
  42. public void updateUser(User user) {
  43. try {
  44. String sql = "UPDATE user SET username=?,password=?,cellphone=? WHERE id=?";
  45. QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
  46. queryRunner.update(sql, new Object[]{user.getUsername(), user.getPassword(), user.getCellphone(), user.getId()});
  47. } catch (SQLException e) {
  48. new RuntimeException("登陆失败了!");
  49. }
  50. }
  51. }
  1. package zhongfucheng.service;
  2. import zhongfucheng.dao.UserDao;
  3. import zhongfucheng.entity.User;
  4. import zhongfucheng.utils.WebUtils;
  5. import java.util.List;
  6. /**
  7. * Created by ozc on 2017/5/3.
  8. */
  9. public class Service {
  10. UserDao userDao = new UserDao();
  11. public void add(User user) {
  12. //手动设置id,因为在数据库表我没使用自动增长id
  13. user.setId(WebUtils.makeId());
  14. //这是以前的表,规定要address,只能手动设置了
  15. user.setAddress("广州");
  16. userDao.add(user);
  17. }
  18. public User findUser(String id) {
  19. return userDao.findUser(id);
  20. }
  21. public List<User> getAll() {
  22. return userDao.getAll();
  23. }
  24. public void updateUser(User user) {
  25. userDao.updateUser(user);
  26. }
  27. }
  • 编写添加用户JSP
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <%@taglib prefix="s" uri="/struts-tags" %>
  3. <html>
  4. <head>
  5. </head>
  6. <body>
  7. <form action="${pageContext.request.contextPath}/user_register" method="post">
  8. <table border="1">
  9. <tr>
  10. <td>用户名:<input type="text" name="username"></td>
  11. </tr>
  12. <tr>
  13. <td> 密码:<input type="password" name="password"></td>
  14. </tr>
  15. <tr>
  16. <td>电话:<input type="text" name="cellphone"></td>
  17. </tr>
  18. <tr>
  19. <td><input type="submit" value="提交"></td>
  20. </tr>
  21. </table>
  22. </form>
  23. </body>
  24. </html>
  • 使用了模型驱动封装数据,添加用户
  1. //这里一定要实例化
  2. User user = new User();
  3. public User getUser() {
  4. return user;
  5. }
  6. public void setUser(User user) {
  7. this.user = user;
  8. }
  9. @Override
  10. public User getModel() {
  11. return user;
  12. }
  13. /*******调用service********/
  14. Service service = new Service();
  15. public String register() throws Exception {
  16. service.add(user);
  17. //注册成功,就跳转到list()方法,list方法就跳转到查看所有用户页面了!
  18. return list();
  19. }
  • 列出全部的用户数据,提供修改功能,需要把id传递过去,明确修改的是哪一个用户
  1. <%--
  2. Created by IntelliJ IDEA.
  3. User: ozc
  4. Date: 2017/5/2
  5. Time: 18:24
  6. To change this template use File | Settings | File Templates.
  7. --%>
  8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  9. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  10. <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
  11. <%@ taglib prefix="s" uri="/struts-tags" %>
  12. <html>
  13. <head>
  14. <title>列出下载页面</title>
  15. </head>
  16. <body>
  17. <table border="1" align="center">
  18. <tr>
  19. <td>用户id</td>
  20. <td>用户姓名</td>
  21. <td>用户密码</td>
  22. <td>用户电话</td>
  23. <td>操作</td>
  24. </tr>
  25. <s:if test="#request.users!=null">
  26. <c:forEach items="${users}" var="user">
  27. <tr>
  28. <td>${user.id}</td>
  29. <td>${user.username}</td>
  30. <td>${user.password}</td>
  31. <td>${user.cellphone}</td>
  32. <td><a href="${pageContext.request.contextPath}/user_updatePage?id=${user.id}">修改</a></td>
  33. </tr>
  34. </c:forEach>
  35. </s:if>
  36. </table>
  37. </body>
  38. </html>
  • Action得到web带过来的id,找到对象,添加到值栈中(数据回显)
  1. public String updatePage() throws Exception {
  2. //得到用户带过来的id,根据id查找对象
  3. User user222 = service.findUser(user.getId());
  4. ActionContext.getContext().getValueStack().push(user222);
  5. return "updatePage";
  6. }
  • 修改用户的JSP页面,使用Struts2提供的回显技术,并把id通过隐藏域带过去给Action..最终是通过id来修改用户的数据
  1. <form action="${pageContext.request.contextPath}/user_update">
  2. <table border="1">
  3. <tr>
  4. <td>用户名<s:textfield name="username"/></td>
  5. </tr>
  6. <tr>
  7. <td>密码 <s:textfield name="password" /></td>
  8. </tr>
  9. <tr>
  10. <td>电话<s:textfield name="cellphone"/></td>
  11. </tr>
  12. <s:hidden name="id"/>
  13. <tr>
  14. <td><input type="submit" value="修改"></td>
  15. </tr>
  16. </table>
  17. </form>

这里写图片描述


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

这里写图片描述

  1. <table border="1">
  2. <s:token></s:token>
  3. <tr>
  4. <td>用户名:<input type="text" name="username"></td>
  5. </tr>
  6. <tr>
  7. <td> 密码:<input type="password" name="password"></td>
  8. </tr>
  9. <tr>
  10. <td>电话:<input type="text" name="cellphone"></td>
  11. </tr>
  12. <tr>
  13. <td><input type="submit" value="提交"></td>
  14. </tr>
  15. </table>

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

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

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
  4. "http://struts.apache.org/dtds/struts-2.0.dtd">
  5. <struts>
  6. <constant name="struts.ui.theme" value="simple"/>
  7. <package name="xxx" extends="struts-default">
  8. <action name="user_*" class="zhongfucheng.action.UserAction" method="{1}">
  9. <interceptor-ref name="defaultStack"/>
  10. <interceptor-ref name="token">
  11. <!-- 要拦截的方法! -->
  12. <param name="includeMethods">register</param>
  13. </interceptor-ref>
  14. <!--如果是list,那么就跳转到list的JSP页面-->
  15. <result name="list"> /list.jsp</result>
  16. <!--请求跳转到修改页面-->
  17. <result name="updatePage">/update.jsp</result>
  18. <!--如果校验成功,跳转到login.jsp页面回显-->
  19. <result name="success">/login.jsp</result>
  20. <result name="redirectList" type="redirect">/user_list</result>
  21. </action>
  22. </package>
  23. <include file="config.xml"/>
  24. </struts>
  • 当我们重复提交的时候,它会报错,因此,如果它报错了,我们就跳转到register页面把

这里写图片描述

这里写图片描述

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y

版权声明:本文为Java3y原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Java3y/p/8544460.html