• 背景:

通过上一章节《Struts(十六):通过CURD来学习Struts流程及ModelDriven的用法》学习了ModelDriven拦截器的用法,上章节中讲到了edit功能。

要修改一个member信息时:

1、首先通过url传入一个id参数:member-list.jsp中

            <td><s:a href="member-view.action?id=%{id}" >view</s:a></td>
<td><s:a href="member-edit.action?id=%{id}" >edit</s:a></td>
<td><s:a href="member-delete.action?id=%{id}" >delete</s:a></td>

2、MemberAction.java的edit函数:

    public String edit() {
// 1、根据id从数据库中,获取id对应的member对象
Member member_ = memberDao.get(this.member.getId()); // 2、把从数据库中获取的属性放入值栈的属性中
this.member.setAge(member_.getAge());
this.member.setName(member_.getName());
this.member.setGender(member_.getGender()); return "edit";
}

3、表单form-edit.jsp:

    <s:debug></s:debug>
<s:form action="member-save.action">
<s:textfield name="id" label="ID"></s:textfield>
<s:textfield name="name" label="Name"></s:textfield>
<s:textfield name="age" label="Age"></s:textfield>
<s:radio list="#{'male':'male','female':'female' }" name="gender" label="Gender"></s:radio>
<s:submit name="submit" label="提交"></s:submit>
</s:form>

流程分析图:

根据上边的代码,调试form-edit.jsp页面当打开s:debug我们确实看到了栈顶对象被填充值了:

4、修改MemberAction.java的edit方法,并调试产看member-edit.jsp debug内容:

    public String edit() {
// // 1、根据id从数据库中,获取id对应的member对象
// Member member_ = memberDao.get(this.member.getId());
//
// // 2、把从数据库中获取的属性放入值栈的属性中
// this.member.setAge(member_.getAge());
// this.member.setName(member_.getName());
// this.member.setGender(member_.getGender());
//
this.member= memberDao.get(this.member.getId()); return "edit";
}

这是为什么呢?

---getModel()返回的对象是存放在栈顶的对象,而修改后的对象是Dao中返回的对象,这两个对象不是同一个对象的原因。

我们是否能通过其他方式来实现这个功能呢?

  • 自动填写了memeber-edit.jsp表单页面改写方案(paramsPrepareParamsStack方案)

方案一:把重新赋值后的this.member对象压入栈顶

    public String edit() {
// // 1、根据id从数据库中,获取id对应的member对象
// Member member_ = memberDao.get(this.member.getId());
//
// // 2、把从数据库中获取的属性放入值栈的属性中
// this.member.setAge(member_.getAge());
// this.member.setName(member_.getName());
// this.member.setGender(member_.getGender()); this.member = memberDao.get(this.member.getId());
ActionContext.getContext().getValueStack().push(this.member); return "edit";
}

不错这样是可以自动填写了memeber-edit.jsp表单页面,但是我们查看s:debug下发现值栈中有两个member对象:

方案二:使用paramsPrepareParams拦截器栈

1、修改struts.xml来实现修改当前项目struts2的拦截器栈

在package标签下添加配置:<default-interceptor-ref name="paramsPrepareParamsStack"></default-interceptor-ref>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<constant name="struts.devMode" value="false" /> <package name="default" namespace="/" extends="struts-default">
<default-interceptor-ref name="paramsPrepareParamsStack"></default-interceptor-ref>
<action name="member-*" class="com.dx.struts.actions.MemberAction"
method="{1}">
<result name="{1}">/member-{1}.jsp</result>
<result name="delete" type="redirectAction">member-list</result>
<result name="modify" type="redirectAction">member-list</result>
<result name="create" type="redirectAction">member-list</result>
</action>
</package>
<!-- Add packages here -->
</struts>

2、对MemberAction.java进行修改:

1)添加id属性,并实现其set方法,目的是:实现在调用ModelDriven的getModel函数前,通过Params调用该set方法实现对id属性赋值,因此可以在getModel内部使用该属性判定是否页面传递了该参数。

2)修改MemberAction.java自身方法。

修改后代码如下:

/**
* @author Administrator
*
*/
package com.dx.struts.actions; import java.util.Date;
import java.util.List;
import java.util.Map; import org.apache.struts2.interceptor.RequestAware; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven; import com.dx.struts.dao.MemberDao;
import com.dx.struts.entity.Member; /**
* ModelDriven 和Preparable拦截器
*/
public class MemberAction implements RequestAware, ModelDriven<Member> {
private MemberDao memberDao = new MemberDao();
private Member member;
private Long id; // Params拦截器 负责赋值id时,调用了该函数。
public void setId(Long id) {
this.id = id;
} public String list() {
List<Member> members = memberDao.getMembers();
request.put("members", members);
return "list";
} public String view() {
// // 1、获取传入的id:member.getId();
// // 2、根据id获取member对象;
// Member member_ = memberDao.get(this.member.getId());
//
// // 3、赋值栈顶对象的属性:此时栈顶对象为member对象。
// member_.setAge(this.member.getAge());
// member_.setName(this.member.getName());
// member_.setGender(this.member.getGender());
//
return "view";
} public String delete() {
// memberDao.remove(this.member.getId());
memberDao.remove(this.id);
// 返回结果的类型应该为:redirectAction
// 也可以是chain:实际上chain是没有必要的,因为不需要在下一个action中保留啊当前action的状态
// 若使用chain,则到达目标页面后,地址栏显示的依然是删除的那个链接,则刷新时会重复提交。
return "delete";
} public String edit() {
// // 1、根据id从数据库中,获取id对应的member对象
// Member member_ = memberDao.get(this.member.getId());
//
// // 2、把从数据库中获取的属性放入值栈的属性中
// this.member.setAge(member_.getAge());
// this.member.setName(member_.getName());
// this.member.setGender(member_.getGender()); // this.member = memberDao.get(this.member.getId());
// ActionContext.getContext().getValueStack().push(this.member); return "edit";
} public String save() {
//.... return "modify";
} public String create() {
member.setId(new Date().getTime());
memberDao.add(member); return "create";
} private Map<String, Object> request; @Override
public void setRequest(Map<String, Object> request) {
this.request = request;
} @Override
public Member getModel() {
// 如果需要在这个函数调用调用了ModelDriven拦截器栈之前就初始化参数id的拦截器栈的Params拦截器。
// 经过查看DefaultStack拦截器栈中ModelDriven拦截器之前并没有Params拦截器,说明该默认拦截器已经不够用了,
// 但是我们发现在struts2-core.jar下struts-default.xml下除了DefaultStack拦截器栈外还有paramsPrepareParamsStack拦截器栈,
// 而该拦截器栈中恰好在ModelDriven拦截器栈之前和之后都调用了一次Params拦截器。
// 修改struts.xml package标签下添加配置:<default-interceptor-ref name="paramsPrepareParamsStack"></default-interceptor-ref> // 如果没有id请求参数,说明为create
if (this.id == null) {
this.member = new Member();
}
// 如果有id请求参数,说明为edit
else {
this.member = memberDao.get(this.id);
}
return this.member;
}
}
  • 值栈paramsPrepareParamsStack方案总结

不足之处(资源浪费):

1、在执行删除的时候,id不为null,但是getModel方法执行了一次从数据库中空加载;

2、当执行查询信息时,也空执行了一次new Member()对象。

Struts(十七):通过CURD来学习paramsPrepareParams拦截器栈的更多相关文章

  1. Struts(十八):通过CURD来学习PrepareInterceptor拦截器

    PrepareInterceptor拦截器的用法: 1.若Action实现了Preparable接口,则Action方法需实现prepare()方法: 2.PrepareInterceptor拦截器S ...

  2. Struts2学习之拦截器栈

    © 版权声明:本文为博主原创文章,转载请注明出处 拦截器栈: - 从结构上看:拦截器栈相当于多个拦截器的组合 - 从功能上看:拦截器栈也是拦截器 默认拦截器栈: - 在struts-core.jar中 ...

  3. SpringMVC学习 十三 拦截器栈

    拦截器栈:就是有多个拦截器同时拦截相同的控制器(controller)请求,这写拦截器就构成了拦截器栈. 栈的特点是先进后出,在拦截器栈中也是如此,如果先执行了preHandle方法,也就是意味着先进 ...

  4. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. Struts 2学习笔记——拦截器相关

    一.添加国际化支持 默认的struts-deault.xml文件中已经定义了国际化拦截器,内容如下 <!-定义国际化拦截器--> <interceptor name="i1 ...

  6. 【Java EE 学习 69 上】【struts2】【paramsPrepareParamsStack拦截器栈解决model对象和属性赋值冲突问题】

    昨天有同学问我问题,他告诉我他的Action中的一个属性明明提供了get/set方法,但是在方法中却获取不到表单中传递过来的值.代码如下(简化后的代码) public class UserAction ...

  7. struts2学习笔记--拦截器(Interceptor)和登录权限验证Demo

    理解 Interceptor拦截器类似于我们学过的过滤器,是可以在action执行前后执行的代码.是我们做web开发是经常使用的技术,比如权限控制,日志.我们也可以把多个interceptor连在一起 ...

  8. Struts2基础学习(五)—拦截器

    一.概述 1.初识拦截器      Interceptor 拦截器类似前面学过的过滤器,是可以在action执行前后执行的代码,是我们做Web开发经常用到的技术.比如:权限控制.日志等.我们也可以将多 ...

  9. struts2学习(5)拦截器简介以及例子执行过程

    一.拦截器简介: 二.Struts2预定义拦截器&拦截器栈 在执行action之前和之后,拦截器进行了操作: 比如struts-default.xml中就有很多预定义的拦截器:   拦截器栈: ...

随机推荐

  1. 51ak带你看MYSQL5.7源码3:修改代码实现你的第一个Mysql版本

    从事DBA工作多年 MYSQL源码也是头一次接触 尝试记录下自己看MYSQL5.7源码的历程 目录: 51ak带你看MYSQL5.7源码1:main入口函数 51ak带你看MYSQL5.7源码2:编译 ...

  2. 关于try catch finally

    一.try catch finally的初步理解 首先,我们什么时候要用到try/catch和finally? --已知执行的代码有可能有异常的情况下 try { //这里执行的代码如果出现异常,则立 ...

  3. SpringBoot中MongoDB注解概念及使用

    spring-data-mongodb主要有以下注解 @Id 主键,不可重复,自带索引,可以在定义的列名上标注,需要自己生成并维护不重复的约束.如果自己不设置@Id主键,mongo会自动生成一个唯一主 ...

  4. 蓝牙4.0模块控制LED彩灯调光调色经验之谈

    基于蓝牙模块的智能LED彩灯调光调色控制思路如下: 在此,找一个低功耗蓝牙模块内嵌接入LED灯的控制电路板,接入LED彩灯的控制电路中. 蓝牙模块彩灯控制方式如下,本文两类来解说led灯的控制方式: ...

  5. CentOS 6.5 通过命令行安装发送邮件

    1.安装sendmail: yum install sendmail 2.安装mailx: yum install mailx -y 3.编辑发送的配置文件: vi /etc/mail.rc #在最后 ...

  6. Dynamics 365 for CRM:CRM与ADFS安装到同一台服务器,需修改ADFS服务端口号

    CRM与ADFS安装到同一台服务器时,出现PluginRegistrationTool 及 CRM Outlook Client连接不上,需要修改ADFS的服务端口号,由默认的808修改为809: P ...

  7. centos 7.0远程登录

    http://blog.csdn.net/e1219092641/article/details/79586476 linux在虚拟机上操作也是有许多不便之处的,但是远程登录的使用可以使操作简单不少, ...

  8. VS2017调试器无法附加到IIS进程(w3wp.exe)

    问题描述: 当使用VS2017-> 调试->附加到进程来调试IIS进程(w3wp.exe)时,报错"无法附加到进程,已附加了一个调试器" 为了解决这个问题花了不少时间, ...

  9. Java8学习(4)-Stream流

    Stream和Collection的区别是什么 流和集合的区别是什么? 粗略地说, 集合和流之间的差异就在于什么时候进行计算.集合是一个内存中的数据结构,它包含数据结构中目前所有的值--集合中的每个元 ...

  10. [福大软工] W班 软工实践原型设计—成绩公布

    作业地址 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/909 作业要求 详见作业地址 存在问题 1. ...