Struts2当中数据封装的三种机制:属性驱动、标签驱动、模型驱动。下面来一一介绍。



一、属性驱动

1、需要提供对应属性的set方法进行数据的封装。

2、表单的哪些属性需要封装数据,那么在对应的Action类中提供该属性的set方法即可。

3、表单中的数据提交,最终找到Action类中的setXxx的方法,最后赋值给全局变量。

4、注意:Struts2的框架采用的拦截器完成数据的封装。

5、注意:这种方式不是特别好:因为属性特别多,提供特别多的set方法,而且还需要手动将数据存入到对象中.

6、注意:这种情况下,Action类就相当于一个JavaBean,就没有体现出MVC的思想,Action类又封装数据,又接收请求处理,耦合性较高。

具体来看一个action的实现:

public class LoginActio extends ActionSupport{
//Action需要处理表单提交的两个数据:用户名和密码。
//此处的属性值应与表单中的name值一致
//并且必须得有对应的set和get方法
private String username;//与表单的相应name一致
private String password;
@Override
public execute()throws Exception{
System.out.println("username="+username);
System.out.println("password="+password);
return"success";
}
public String getUsername() {
return username;
}
publicvoid setUsername(String username) {
this.username= username;
}
public String getPassword() {
return password;
}
publicvoid setPassword(String password) {
this.password= password;
}
}

表单提交格式如下:

<form action="LoginActio" method="post">
<input type="text" name="username">
<input type="text" name="password">
<button type="submit">提交</button>
</form>

在配置完成后便可以将表单中form中的的action属性改为当前的action的name(注意后缀是.action,也可自行设置,使用constant属性)。然后启动项目转到相应页面中输入用户名和密码后可以看到在控制台中已经打印出来了相关信息。

但是我们却并没有在代码中做过任何相关的数据封装操作,但是对应的数据却已经被封装到属性当中了。

这便是struts2的数据封装中的属性封装机制,只需在Action中设置当前表单中要提交的数据的属性(注意这里可能会存在属性类型的转换问题,这个例子只涉及到String类型的属性,同时表单中提交的数据也是String类型的。所有不牵扯到类型转换问题)待表单提交过来数据时便直接会被封装到对应的属性中去。事实上这是通过java的反射机制实现的。



二、标签驱动

可以通过在页面上使用OGNL表达式进行数据封装。想要通过Struts2中的标签来实现表单数据的自动封装的前提是得在表单中加入Struts2标签支持。

<%@taglib prefix="s" uri="/struts-tags" %>

1、在页面中使用OGNL表达式进行数据的封装,就可以直接把属性封装到某一个JavaBean的对象中。

2、在页面中定义一个JavaBean,并且提供set方法:例如:private User user;

3、页面中的编写发生了变化,需要使用OGNL的方式,表单中的写法:<input type="text" name="user.username">

4、注意:只提供一个set方法还不够,如果没有user实例化,必须还需要提供user属性的get和set方法,先调用get方法,判断一下是否有user对象的实例对象,如果没有,调用set方法把拦截器创建的对象注入进来。

具体的Action实例如下:

//省略包导入
/**
* 动态参数封装:属性驱动
* OGNL
* 所有的封装动态参数操作:都是一个叫params的拦截器封装的。
*/
public class TestAction extends ActionSupport { private User user = new User();//User是一个封装好了的javaBean模型 public String execute(){
System.out.println("name is "+user.getName()+" and age is "+user.getAge());
return SUCCESS;
} public User getUser() {
System.out.println("getUser");
return user;
} public void setUser(User user) {
System.out.println("setUser");
this.user = user;
}
}

form表单提交如下:

<%--动态参数封装:对象导航映射
此时表单元素的name属性取值已经不是一个普通的字符串了。
而是一个OGNL表达式。
OGNL:Object Graphic Navigationg Language
对象 图 导航 语言
--%>
<form action="${pageContext.request.contextPath}/testAction.action" method="post">
用户名:<input type="text" name="user.name"/><br/>
年龄:<input type="text" name="user.age"/><br/>
<input type="submit" value="提交"/>
</form>

还可以使用struts2的标签:

<%--这里定位action的方式是和配置struts.xml差不多,使用namespace和action名--%>
<s:form namespace="/normal" action="testAction.action" method="POST">
<%--name属性也必须这样写--%>
<s:textfield name="user.name"/>
<s:password name="user.passwd"/>
<s:submit>提交</s:submit>
</s:form>

三、模型驱动。

使用模型驱动的方式,也可以把表单中的数据直接封装到一个JavaBean的对象中,并且表单的写法和之前的写法没有区别!编写的页面不需要任何变化,正常编写name属性的值。

模型驱动的编写步骤

* 手动实例化JavaBean,即:private User user = new User();

* 相应的Action必须实现ModelDriven<T>接口,实现getModel()的方法,在getModel()方法中返回user即可!!

下面看一个Action实例:

// 实现ModelDriven接口,泛型中写了我们封装的数据,也就是我们自己编写的javaBean对象User
public class StudentAction extends ActionSupport implements ModelDriven<User> {
// 我们必须实例化我们封装的数据,struts2会直接使用我们的这个类,将数据set进去
// 所以我们必须在这个类中写get和set方法
private User u = new User();//实例化javaBean // 实现此接口必须实现的方法,返回我们封装的数据,也就是javaBean对象
@Override
public User getModel() {
return u;
} @Override
// 这种方法我们完全没有设置什么,但是struts2依然为我们将数据放了进去
// 这里其实是java反射的应用
public String execute() throws Exception {
System.out.println(u.getName());
System.out.println(u.getPasswd());
return "success";
}
}

而form表单的提交方式和第一种属性驱动的方式一模一样,无需更改。

上述方式实现的大致原理如下:

* 当请求发送到action之前,调用我们自定义的Action类中的getModel方法,获取封装表单数据的javaBean对象

* 获得该对象之后,我们便可以获得对应的类类型 

* 利用反射可以获取到类中的属性列表 

* 通过request.getParameterNames()可以获取表单中的name列表 

* 判断name值和属性名称,一致的情况下,反射调用属性的set方法来给对应的属性值设置参数 

* 最后完成完成数据的封装 



四、Action对集合对象的封装

1、把数据封装到Collection中

因为Collection接口都会有下标值,所有页面的写法会有一些区别,注意:

<input type="text" name="products[0].name" />

在Action中的写法,需要提供products的集合,并且提供get和set方法



2、把数据封装到Map中

Map集合是键值对的形式,页面的写法

<input type="text" name="map['one'].name" />

Action中提供map集合,并且提供get和set方法。



**在Action中不推荐使用模型驱动的方式来封装数据到集合中。

Struts2中数据封装机制的更多相关文章

  1. Struts2中数据封装方式

    一.通过ActionContext类获取 public class ActionContextDemo extends ActionSupport {    @Override    public S ...

  2. struts2中struts.xml配置文件详解【未整理】

    1.    深入Struts2的配置文件 本部分主要介绍struts.xml的常用配置. 1.1.    包配置: Struts2框架中核心组件就是Action.拦截器等,Struts2框架使用包来管 ...

  3. Struts2中Action接收参数的方法主要有以下三种:

    Struts2中Action接收参数的方法主要有以下三种: 1.使用Action的属性接收参数(最原始的方式):     a.定义:在Action类中定义属性,创建get和set方法:     b.接 ...

  4. struts2中各个jar包作用

    Struts2.3.4 所需的Jar包及介绍 Jar包的分类 jar包名称 jar包版本 jar包 文件名 jar包 的作用 jar包内包含的主要包路径及主要类 依赖的自有jar包名称 依赖的第三方j ...

  5. struts2中的jar包

    核心包: (后面数字是版本号,不同struts2版本,数字可能不一样.) struts2-core-2.1.8.1 struts2的核心jar包,不可缺少的 xwork-core-2.1.6 xwor ...

  6. struts2中的jsp值传到后台action接收的三种方法

    struts2中的Action接收表单传递过来的参数有3种方法: 如,登陆表单login.jsp: <form action="login" method="pos ...

  7. 简单理解Struts2中拦截器与过滤器的区别及执行顺序

    简单理解Struts2中拦截器与过滤器的区别及执行顺序 当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标 ...

  8. 5.Struts2中的拦截器

    拦截器是Struts2中的核心,其自带很多很多的拦截器,这里主要介绍一下自定义拦截器,恩多一半情况下呢?我们不需要使用到自定义的拦截器,Struts2本身已经提 供了很多的拦截器供我们使用,对于自定义 ...

  9. struts2中如何使用主题theme

    一.什么是主题? 主题就是一种风格化标签,能够让所有UI标签能够产生同样的视觉效果而归集到一起的一组模板,即风格相近的模板被打包为一个主题 二.struts2提供的主题有哪些呢?struts2中如何修 ...

随机推荐

  1. comet realization with ajax&php

    1.prepare front-end code, meta content-type cannot be ignored! as to the xhr, status should be 3 < ...

  2. 转 PHP 使用 Redis

    PHP 使用 Redis PHP 使用 Redis 安装 开始在 PHP 中使用 Redis 前, 我们需要确保已经安装了 redis 服务及 PHP redis 驱动,且你的机器上能正常使用 PHP ...

  3. Beyond compare vs kdiff3

    這裡使用的 kdiff3 版本是 0.9.98   基於以下 三點,最終選擇了 beyond compare   1. kdiff3 不能刪檔案,     以下為例,不能刪1   2. kdiff3 ...

  4. getID3类的学习使用

    getID3类的学习使用 网上描述: getID3()这个PHP脚本能够从MP3或其它媒体文件中提取有用的信息如:ID3标签,bitrate,播放时间等. (格式包括:Ogg,WMA,WMV,ASF, ...

  5. HRBUST 2072:萌萌哒十五酱的礼物~(树,字典树)

    题意:n个点的一棵树,树的边上有权值.一条路径的权值定义成这条路径上所有边的权值的xor.问所有路径的最大权值是多少. 思路: 首先,树上任意两点之间的路可以表示成 这两点到根节点的路- 其最近公共祖 ...

  6. 焦作F Modular Production Line 费用流

    题目链接 题解:这道题比赛的时候,学弟说是网络流,当时看N这么大,觉得网络流没法做,实际本题通过巧妙的建图,然后离散化. 先说下建图方式,首先每个覆盖区域,只有左右端点,如果我们只用左右端点的话,最多 ...

  7. 牛客网 牛客小白月赛1 A.简单题-控制输出格式setiosflags()函数+setprecision()函数

    水一水博客,都不好意思写这篇博客,毕竟已经不是大一的了. 难得能把一整套题都写出来(日常智障).但是在这里不写G题あなたの蛙は旅⽴っています的题解. 有毒,G题关了流同步只能过94%的样例,说我运行超 ...

  8. logging模块详解以及常见代码

    1.在django中获取客户端IP地址: if 'HTTP_X_FORWARDED_FOR' in request.META: ip = request.META['HTTP_X_FORWARDED_ ...

  9. BT原理分析(转)

    BT种子文件结构分析,参考:http://www.cnblogs.com/EasonJim/p/6601047.html BT下载,参考:http://baike.baidu.com/item/BT下 ...

  10. Intent 传递对象

    方法: 可以让这个要传递的对象所属类实现Serializable或者Parcelable接口, 然后利用onCreate函数中的Bundle参数作为载体,传递这个对象. 例如: <span st ...