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



一、属性驱动

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

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

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

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

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

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

具体来看一个action的实现:

  1. public class LoginActio extends ActionSupport{
  2. //Action需要处理表单提交的两个数据:用户名和密码。
  3. //此处的属性值应与表单中的name值一致
  4. //并且必须得有对应的set和get方法
  5. private String username;//与表单的相应name一致
  6. private String password;
  7. @Override
  8. public execute()throws Exception{
  9. System.out.println("username="+username);
  10. System.out.println("password="+password);
  11. return"success";
  12. }
  13. public String getUsername() {
  14. return username;
  15. }
  16. publicvoid setUsername(String username) {
  17. this.username= username;
  18. }
  19. public String getPassword() {
  20. return password;
  21. }
  22. publicvoid setPassword(String password) {
  23. this.password= password;
  24. }
  25. }

表单提交格式如下:

  1. <form action="LoginActio" method="post">
  2. <input type="text" name="username">
  3. <input type="text" name="password">
  4. <button type="submit">提交</button>
  5. </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实例如下:

  1. //省略包导入
  2. /**
  3. * 动态参数封装:属性驱动
  4. * OGNL
  5. * 所有的封装动态参数操作:都是一个叫params的拦截器封装的。
  6. */
  7. public class TestAction extends ActionSupport {
  8.  
  9. private User user = new User();//User是一个封装好了的javaBean模型
  10.  
  11. public String execute(){
  12. System.out.println("name is "+user.getName()+" and age is "+user.getAge());
  13. return SUCCESS;
  14. }
  15.  
  16. public User getUser() {
  17. System.out.println("getUser");
  18. return user;
  19. }
  20.  
  21. public void setUser(User user) {
  22. System.out.println("setUser");
  23. this.user = user;
  24. }
  25. }

form表单提交如下:

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

还可以使用struts2的标签:

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

三、模型驱动。

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

模型驱动的编写步骤

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

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

下面看一个Action实例:

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

而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. 【BZOJ1901】Dynamic Rankings(树套树,树状数组,主席树)

    题意:给定一个N个数的序列,要求维护一个数据结构支持以下两种操作: 1:将第X个数改成Y 2:查询第X到第Y个数里第K小的数是多少 n,m<=10000,a[i]<=10^9 思路:单点修 ...

  2. 转 Python爬虫入门四之Urllib库的高级用法

    静觅 » Python爬虫入门四之Urllib库的高级用法 1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我 ...

  3. 标准C程序设计七---117

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  4. Vue中的computed 解读

    computed相当于属性的一个实时计算,如果实时计算里关联了对象,那么当对象的某个值改变的时候,同事会出发实时计算.比如: <body id="content"> & ...

  5. poj 2253(kruskal)

    Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 34968   Accepted: 11235 Descrip ...

  6. 美图秀秀web开发文档

    Xiuxiu 组件 import React, { Component } from 'react'; class XiuXiu extends Component { componentDidMou ...

  7. 数据库SQL Server 2014 设置自动备份(维护计划和作业)

    前言     1.SQL Server数据库自动备份可以有两种操作          第一种是在SQL控制台下的服务器名称展开,展开“管理”--选择“维护计划”,右键“新建维护计划”即可.       ...

  8. 2017-11-07-noip模拟题

    T1 数学老师的报复 矩阵快速幂模板,类似于菲波那切数列的矩阵 [1,1]*[A,1 B,0] #include <cstdio> #define LL long long inline ...

  9. socket的accept: Invalid argument问题

    void local_sdk_server::wait_remote_client_connect_and_comm() { /*服务器服务启动,等待客户端的链接的到来*/ //sockaddr_in ...

  10. 嗅探X-Windows服务按键工具xspy

    嗅探X-Windows服务按键工具xspy   X-Windows完整名字是X Windows图形用户接口.它是一种计算机软件系统和网络协议.它为联网计算机提供了一个基础的图形用户界面(GUI)和丰富 ...