struts2(三)--运行流程

Struts2会把请求参数给栈顶对象的属性。


该流程以Employee的增删改查为例进行整个流程的讲解
在这里插入图片描述

显示和删除员工信息列表流程

定义两个jsp页面

index.jsp:用于发送显示员工信息的请求。
在这里插入图片描述
删除某个员工的请求:
在这里插入图片描述
emp-list.jsp:用于显示员工信息的页面。

Struts.xml

在这里插入图片描述

Employee.java

实体类,用于定义员工的相关信息。
在这里插入图片描述

EmployeeAction.java

在这里插入图片描述

Dao.java

进行增删改查操作。
在这里插入图片描述

运行流程

从发请求到调用action方法的流程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在到达目标action方法之前,Struts2会经过一系列的拦截器。
在这里插入图片描述

Params拦截器

Parameters拦截器将把表单字段映射到ValueStack栈的栈顶对象的各个属性中,如果某个字段在模型里没有匹配的属性,那么该拦截器将尝试ValueStack栈中的下一个对象,默认情况下,栈顶对象为当前的Action,于是请求参数就是给Action的字段
在这里插入图片描述

ModelDriven拦截器

当删除指定Id的员工或者是向列表中添加一个员工信息时,使用的属性都是在当前EmployeeAction中定义相关属性,以接受请求参数,当属性比较多时就很复杂,然后就可以采用直接将请求参数赋值给一个Employee对象的方式,这个时候就需要ModelDriven拦截器了。
该拦截器实现将Action和Model隔开
在这里插入图片描述

实现方式

EmployeeAction中实现ModelDriven接口并重写getModel()方法。
在这里插入图片描述

在这里插入图片描述
Action实现ModelDriven接口后的运行流程:

  1. 先会执行 ModelDrivenInterceptorintercept方法
    在这里插入图片描述

  2. 执行ParametersInterceptorintercept方法:把请求参数的值赋给栈顶对象对应的属性。若栈顶对象没有对应的属性,则查询值栈中下一个对象对应的属性。

  3. 注意: getModel 方法不能提供以下实现:

public Employee getModel() {
	return new Employee();
}

这样做的确会返回一个 Employee 对象到值栈的栈顶, 但当前 Action 的 employee 成员变量却是 null。

edit修改方法流程总结

该方法将在页面上显示表单,在表单中回显员工的详细信息。
1. 发送请求
在这里插入图片描述
2. 核心处理
回显问题:只要在值栈的栈顶有一个对应的对象,对象的属性与表单的属性一一对应的话,就会自动的赋上。
方式一:可行
在这里插入图片描述
方式二:不可行
在这里插入图片描述
方式三:可行,但有缺陷
在这里插入图片描述
方式四:最终版(可行)
在这里插入图片描述
此时的edit()函数中只有一行代码:
在这里插入图片描述

使用 paramsPrepareParamsStack 拦截器栈后的运行流程

  1. paramsPrepareParamsStackdefaultStack 一样都是拦截器栈.,而 struts-default包默认使用的是defaultStack
  2. 可以在 Struts 配置文件中通过以下方式修改使用的默认的拦截器栈
<default-interceptor-ref name="paramsPrepareParamsStack"></default-interceptor-ref>
  1. paramsPrepareParamsStack拦截器的流程:

params -> modelDriven -> params

先把请求参数赋给 Action 对应的属性, 再根据赋给 Action 的那个属性值决定压到值栈栈顶的对象, 最后再为栈顶对象的属性赋值。

对于 edit 操作而言:
I. 先为 EmployeeAction 的 employeeId 赋值
II. 根据 employeeId 从数据库中加载对应的对象, 并放入到值栈的栈顶
III. 再为栈顶对象的 employeeId 赋值(实际上此时 employeeId 属性值已经存在)
IV. 把栈顶对象的属性回显在表单中.

  1. 关于回显: Struts2 表单标签会从值栈中获取对应的属性值进行回显
  2. 存在的问题:
    (1)在执行删除的时候, employeeId 不为 null, 但 getModel 方法却从数据库加载了一个对象. 不该加载!
    (2)指向查询全部信息时, 也 new Employee() 对象. 浪费!
  3. 解决方案: 使用 PrepareInterceptorPreparable接口

PrepareInterceptor

Preparable接口中的prepare()方法主要作用是:为getModel()方法准备model.

Struts2.0中的modelDriven拦截器负责把Action类以外的一个对象压入到值栈栈顶。
而prepare拦截器负责准备为getModel()方法准备model

源代码解析:

在这里插入图片描述
PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes)方法: 在这里插入图片描述
PrefixMethodInvocationUtil.getPrefixedMethod方法:
在这里插入图片描述
总结:

  • PrepareInterceptor将调用prepare() 方法,prepare[ActionMethodName]方法或 prepareDo[ActionMethodName]方法。

  • PrepareInterceptor根据firstCallPrepareDo属性决定获取prepare[ActionMethodName]、prepareDo[ActionMethodName]的顺序。默认情况下先获取prepare[ActionMethodName]方法,如果没有该方法,就寻找 prepareDo[ActionMethodName]方法,如果找到对应的方法就调用该方法。若都不存在, 就都不执行。

  • PrepareInterceptor会根据 alwaysInvokePrepare 属性决定是否执行prepare()方法。

  • 可以为每一个 ActionMethod 准备 prepare[ActionMethdName]方法, 而抛弃掉原来的prepare()方法。

  • PrepareInterceptoralwaysInvokePrepare 属性置为 false, 以避免 Struts2 框架再调用prepare()方法。
    在这里插入图片描述

具体实现
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

paramsPrepareParamsStack拦截器栈

这个栈的拦截器调用顺序为:

params->prepare->modelDriven->params

Struts2.0的设计上要求modelDriven在params之前调用,而业务中prepare要负责准备model,准备model又需要参数,这就需要在prepare之前运行params拦截器设置相关参数。
流程如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值