struts2--3.Ognl与值栈

    xiaoxiao2021-03-25  70

     

    1      Ognl与值栈—和域对象抢生意的

    1 ognl概述

    2 ognl入门案例

    3 什么是值栈

    (1)servlet和action区别

    (2)值栈存储位置

    - 每个action对象里面有一个值栈对象

    - 值栈对象里面有action引用

    4 如何获取值栈对象

    5 值栈内部结构

    (1)root:list集合

    (2)context:map集合

    6 向值栈放数据

    (1)s:debug标签

    (2)向值栈放字符串

    (3)向值栈放对象

    (4)向值栈放list集合

    - set方法

    - push方法

    - 定义变量,get方法

    7 从值栈获取数据

    (1)从值栈获取字符串

    (2)从值栈获取对象

    (3)从值栈获取list集合

    - s:iterator标签使用

    8 EL表达式获取值栈数据

    (1)增强request里面getAttribute方法

    9 ognl表达式 #、%使用

     

    1.1        OGNL概述

    1 之前web阶段,学习过EL表达式,EL表达式在jsp中获取域对象里面的值;ognl可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。它使用相同的表达式去存取对象的属性。

     

    2 OGNL是一种表达式,这个表达式功能更加强大,

    (1)在struts2里面操作值栈数据

    (2)一般把ognl在struts2操作:和struts2标签一起使用操作值栈

     

    3 OGNL不是struts2的一部分,单独的项目,经常和struts2一起使用

           使用ognl时候首先导入jar包,struts2提供jar包

     

    4.三要素

    表达式;根对象,Context对象

     

    1.2        OGNL入门案例

    1 使用ognl+struts2标签实现计算字符串长度

           在java代码中,调用字符串.length();

     

    2 使用struts2标签

    (1)使用jstl时候,导入jar包之外,在jsp页面中引入标签库

    使用struts2标签时候,在jsp中引入标签库

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

     

    (2)使用struts2标签实现操作

     

    1.3        什么是值栈—类似域对象

    1 之前在web阶段,在servlet里面进行操作,把数据放到域对象里面,在页面中使用el表达式获取到,域对象在一定范围内,存值和取值

     

    2 在struts2里面提供本身一种存储机制,类似于域对象,是值栈,可以存值和取值

    (1)在action里面把数据放到值栈里面,在页面中获取到值栈数据

     

    3 servlet和action区别

    (1)Servlet:默认在第一次访问时候创建,创建一次,单实例对象

    (2)Action:访问时候创建,每次访问action时候,都会创建action对象,创建多次,多实例对象

     

    4 值栈存储位置

    (1)每次访问action时候,都会创建action对象,

    (2)在每个action对象里面都会有一个值栈对象(只有一个)

     

    1.4        获取值栈对象的方式

           常用方式:使用ActionContext类里面的方法得到值栈对象

    // 1 获取ActionContext类的对象 ActionContextcontext = ActionContext.getContext(); //2 调用方法得到值栈对象 ValueStack stack1 = context.getValueStack(); 

    2 每个action对象中只有一个值栈对象

     

    栈:

    1.5        值栈内部结构

     

    1.5.1      值栈分为两部分:

    第一部分 root,结构是list集合

    1)一般操作都是root里面数据

     

    第二部分 context,结构map集合

     

    1.5.2      struts2标签 s:debug

    s:debug,使用这个标签可以查看值栈结构和存储值

    (1)访问action,执行action的方法有返回值,配置返回值到jsp页面中,在jsp页面中使用这个标签  [Debug]

           点击超链接看到结构,基本看 root 就行了。

    (2)在action没有做任何操作,栈顶元素是 action引用

    - action对象里面有值栈对象

    - 值栈对象里面有action引用

    1.5.3      读取 ObjectStack 里的对象的属性

    若想访问 ObjectStack 里的某个对象的属性. 可以使用以下几种形式之一:

           ObjectStack里的对象可以通过一个从零开始的下标来引用. ObjectStack 里的栈顶对象可以用 [0] 来引用, 它下面的那个对象可以用 [1] 引用. 若希望返回栈顶对象的 message 属性值:  [0].message 或 [0][“message”] 或 [0][‘message’]

           若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象

           若从栈顶对象开始搜索, 则可以省略下标部分

     

    username: ^<s:property value="[0].username"/>

     

    1.5.4      读取 Context Map 里的对象的属性

    若想访问ContextMap 里的某个对象的属性, 可以使用以下几种形式之一:

           返回 session 中的 code 属性: #session.code

           返回 request 中的 customer 属性的 name 属性值: #request.customer.name

           返回域对象(按 request, session, application 的顺序)的lastAccessDate 属性:#attr.lastAccessDate 

    1.6        向值栈放数据

    1.6.1      向值栈放数据方式

    1.6.1.1       第一种

    获取值栈对象,调用值栈对象里面的 set 方法

    @Override public String execute() throws Exception { //第一种方式使用值栈对象里面的 set方法 //1 获取值栈对象 ActionContextcontext = ActionContext.getContext(); ValueStackstack = context.getValueStack(); //2 调用方法set方法 stack.set("username","老兰"); return "success"; }  

    1.6.1.2       第二种

    获取值栈对象,调用值栈对象里面的  push方法

     

     

    1.6.1.3       第三种 –常用

    action定义变量,生成变量的get方法—常用

    //第三种方式 //定义变量 private String name; //生成 get 方式 public String getName(){ return name; } @Override public String execute() throws Exception { name = "老兰"; return "success"; }

     

    1.6.2      向值栈放对象

    使用场景:以前做修改操作时,会把数据放到域对象中

    1 实现步骤,第三种方式

    第一步 定义对象变量

    第二步 生成变量的get方法

    第三步 在执行的方法里面向对象中设置值

    public classObjectDemoAction extends ActionSupport { //1 定义对象变量 private User user = new User(); //2 生成get方法 public User getUser() { return user; } public String execute() throws Exception { //3 向值栈的user里面放数据 user.setUsername("lucy"); user.setPassword("123"); user.setAddress("美国"); return "success"; } }  

    1.6.3      向值栈放list集合

    第一步 定义list集合变量

    第二步 生成变量的get方法

    第三步 在执行的方法里面向list集合设置值

    public classListDemoAction extends ActionSupport { // 1 定义list变量 private List<User> list = newArrayList<User>(); // 2 get方法 public List<User>getList() { return list; } public String execute() throws Exception { //3 向list中设置值 Useruser1 = newUser(); user1.setUsername("小奥"); user1.setPassword("123"); user1.setAddress("美国"); Useruser2 = newUser(); user2.setUsername("小王"); user2.setPassword("250"); user2.setAddress("越南"); list.add(user1); list.add(user2); return "success"; } }

     

    1.7        从值栈获取数据

           使用struts2的标签+ognl表达式获取值栈数据

                  <s:propertyvalue=”ognl表达式”/>

    不要忘了在struts.xml中的配置

    1.7.1      获取字段和方法

    ·利用 OGNL 调用任何一个 Java 类里的静态字段或方法;被压入到 ValueStack 栈的对象上的公共字段和方法.

           默认情况下, Struts2 不允许调用任意 Java 类静态方法,  需要重新设置struts.ognl.allowStaticMethodAccess 标记变量的值为 true.

           调用一个实例字段或方法的语法, 其中 object 是Object Stack 栈里的某个对象的引用:

    .object.fieldName: [0].datePattern

    .object.methodName(argumentList): [0].repeat(3, Hello);

     

    <li>访问值栈中的action的普通属性: username = <s:property value="username"/> </li> <li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/> | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/> | wrong: <%--<s:propertyvalue="user[age]"/>--%></li> <li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li> <li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li> <li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()"/></li> <li>访问值栈中action的普通方法:<s:property value="m()"/></li> <hr /> <li>访问静态方法:<s:property value="@com.bjsxt.struts2.ognl.S@s()"/></li> <li>访问静态属性:<s:property value="@com.bjsxt.struts2.ognl.S@STR"/></li> <li>访问Math类的静态方法:<s:property value="@@max(2,3)"/></li> 

    1.7.2      获取字符串

    1 向值栈放字符串

    public classValueStackAction extends ActionSupport { private String username; public String getUsername() { return username; } @Override public String execute() throws Exception { username = "老兰"; return "success"; } } 

    2 在jsp使用struts2标签+ognl表达式获取

    获取字符串的值<br />

       <s:property value="username"/>

    1.7.3      获取对象

    1 向值栈放对象

    public classValueStackObjectAction extends ActionSupport { private User user = new User(); public User getUser() { return user; } @Override public String execute() throws Exception { user.setUsername("mary"); user.setPassword("250"); user.setAddress("china"); return "success"; } } 

    2 在页面中获取值

    <br />获取对象的值<br /> <s:property value="user.username"/> <s:property value="user.password"/> <s:property value="user.address"/>

    1.7.4      获取数组类型的属性

      数组型属性:各个元素以逗号分隔, 并且不带方括号

           下标       fun[0]

           length字段: fun.length

    1.7.5      获取list集合

    public classValueStackListAction extends ActionSupport { private List<User> list = newArrayList<User>(); public List<User>getList() { return list; } @Override public String execute() throws Exception { //3 向list中设置值 Useruser1 = newUser(); user1.setUsername("小奥"); user1.setPassword("123"); user1.setAddress("美国"); Useruser2 = newUser(); user2.setUsername("小王"); user2.setPassword("250"); user2.setAddress("越南"); list.add(user1); list.add(user2); return "success"; } } 

    1.7.5.1       第一种方式:

    <br/>获取list的值第一种方式:<br/> <s:property value="list[0].username"/> <s:property value="list[0].password"/> <s:property value="list[0].address"/> <br/> <s:property value="list[1].username"/> <s:property value="list[1].password"/> <s:property value="list[1].address"/>

    1.7.5.2       第二种方式:

    <br/>获取list的值第二种方式:<br/> <!-- 使用struts2标签类似jstl的foreach标签 s:iterator:遍历值栈的list集合 --> <s:iterator value="list"> <!-- 遍历list得到list里面每个user对象 --> <s:property value="username"/> <s:property value="password"/> <s:property value="address"/> <br/> </s:iterator> 

    1.7.5.3       第三种方式:

    获取list的值第三种方式: <br/> <s:iterator value="list" var="user"> <!-- 遍历值栈list集合,得到每个user对象 机制: 把每次遍历出来的user对象放到 context里面 获取context里面数据特点:写ognl表达式, 使用特殊符号 # --> <s:property value="#user.username"/> <s:property value="#user.password"/> <s:property value="#user.address"/> <br/> </s:iterator> 

    1.7.6      获取set类型的属性

           类似list:以逗号分隔, 并且带方括号

           下标:· colors[0]                指定元素

           size方法或关键字 size: colors.size或 colors.size() 长度

           isEmpty()方法或关键字 isEmptycolors.isEmpty 或 colors.isEmpty()              为空

           还可以使用 OGNL 表达式来创建 List, 创建一个 List 与声明一个 Java 数组是相同的: {“Red”, “Black”, “Green”}

     

    <li>访问List:<s:property value="users"/></li> <li>访问List中某个元素:<s:property value="users[1]"/></li> <li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li> <li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li> <li>访问Set:<s:property value="dogs"/></li> <li>访问Set中某个元素:<s:property value="dogs[1]"/></li> 

    1.7.7      访问 Map 类型的属性

           下标: map[key]

           size或 size()

           isEmpty或 isEmpty()         是不是空.

          

    <li>访问Map:<s:property value="dogMap"/></li> <li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li> <li>访问Map中所有的key:<s:property value="dogMap.keys"/></li> <li>访问Map中所有的value:<s:property value="dogMap.values"/></li>

    1.7.8      投影(过滤)

     

    <li>投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li> <li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li> <li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li> <li>投影:<s:property value="users.{$#this.age>1}.{age}== null"/></li> 

    1.7.9      其他操作

    public classSetPushValueStackAction extends ActionSupport { @Override public String execute() throws Exception { //第一种方式使用值栈对象里面的 set方法 //1 获取值栈对象 ActionContextcontext = ActionContext.getContext(); ValueStackstack = context.getValueStack(); //2 调用方法set方法 stack.set("username","老兰"); stack.push("abcd"); return "success"; } }

    1.7.9.1       使用set方法向值栈获取数据,

    获取set方法设置的值  根据名称获取值   <br/>

       <s:property value="username"/> 

    1.7.9.2       使用push方法向值栈获取数据,

    (1)使用push方法设置值,没有名称,只有设置的值

    (2)向值栈放数据,把向值栈放数据存到数组里面,数组名称 top,根据数组获取值

       获取push方法设置的值 <br/>

       <s:property value="[0].top"/>

     

    1.8        EL表达式获取值栈数据(为什么)

     

    1 EL表达式获取域对象值

    使用foreach标签+el表达式获取值栈list集合数据<br/>

    <c:forEach items="${list }" var="user"> ${user.username} ${user.password} ${user.address} <br/> </c:forEach> 

    2 向域对象里面放值使用setAttribute方法,获取值使用getAttribute方法

     

    3 底层增强request对象里面的方法getAttribute方法

    (1)首先从request域获取值,如果获取到,直接返回

    (2)如果从request域获取不到值,到值栈中把值获取出来,把值放到域对象里面

     

    4 查看源代码

     

     

    1.9        OGNL的#、%、[]使用

    1.9.1      #使用—替换el

    1 使用#获取context里面数据—会此就行

     

    2 演示# 操作

    (1)向request域放值

    (2)在页面中使用ognl获取

     

    1.9.2      %使用

           在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有%之后才会识别。

     

    1.9.3      []

    访问root属性时:

     

    1.10    案例-列表功能改造(值栈)

    Jsp:

     

    源代码文件:http://download.csdn.net/detail/qq_26553781/9778694

     

    转载请注明原文地址: https://ju.6miu.com/read-35709.html

    最新回复(0)