struts2之OGNL和struts2标签库和ValueStack对象

OGNL简介: 

  (1)OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。

     struts2框架默认就支持Ognl表达式语言(所以struts必须引用的包:ognl.jar);

  (2)struts2的ognl的作用:页面取值使用;

  (3)OGNL和EL的区别:

     EL表达式语言:用于页面取值,jsp页面取值的标准(默认可以直接使用,应用范围更加广泛);

       OGNL表达式语言:struts2标签默认支持的表达式语言,必须配置struts标签使用,不能离开struts2标签直接使用;

(4)OGNL 有一个上下文(Context)概念,[OgnlContext对象:OgnlContext对象是ognl表达式语言的核心];

     其实上下文就是一个MAP结构,它实现了  java.utils.Map 的接口。

  (5)ognl表达式语言取值,取根元素的值,不用带#符号;ognl表达式语言取值,取非根元素的值,需要带#符号;

用一个OGNL和struts标签结合的实例演示一下struts的标签的强大功能:

1:第一还是引入struts2核心包,省略

2:创建一个实体类,用于测试显示在页面的信息,如User.java,源码如下所示:

 1 package com.bie.ognl;
 2 /** 
 3 * @author BieHongLi 
 4 * @version 创建时间:2017年3月7日 下午8:45:27 
 5 * 
 6 */
 7 public class User {
 8 
 9     private int id;
10     private String name;
11     public int getId() {
12         return id;
13     }
14     public void setId(int id) {
15         this.id = id;
16     }
17     public String getName() {
18         return name;
19     }
20     public void setName(String name) {
21         this.name = name;
22     }
23     public User(int id, String name) {
24         super();
25         this.id = id;
26         this.name = name;
27     }
28     
29     
30 }

3:创建完成实体类之后就可以开始开发action,如OgnlAction.java,源码如下所示:

 1 package com.bie.ognl;
 2 
 3 import java.util.ArrayList;
 4 import java.util.HashMap;
 5 import java.util.List;
 6 import java.util.Map;
 7 
 8 import com.opensymphony.xwork2.ActionContext;
 9 import com.opensymphony.xwork2.ActionSupport;
10 
11 /** 
12 * @author BieHongLi 
13 * @version 创建时间:2017年3月7日 下午8:43:00 
14 * 
15 */
16 public class OgnlAction extends ActionSupport{
17 
18     
19     private static final long serialVersionUID = 1L;
20     @Override
21     public String execute() throws Exception {
22         //测试迭代标签
23         List<User> list=new ArrayList<User>();
24         Map<Integer, User> map=new HashMap<Integer, User>();
25         
26         //初始化
27         for(int i=1;i<11;i++){
28             User user=new User(i,"张三"+i);
29             
30             list.add(user);
31             map.put(user.getId(), user);
32         }
33         
34         //保存list信息
35         ActionContext.getContext().getContextMap().put("list", list);
36         //保存map信息
37         ActionContext.getContext().getContextMap().put("map", map);
38         
39         
40         return "success";
41     }
42     
43 }

4:开发完action,配置struts.xml文件,这里使用主次配置,所以这里配置ognl.xml,然后在struts.xml文件中引入ognl.xml配置文件即可:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
 4     "http://struts.apache.org/dtds/struts-2.0.dtd">
 5  
 6 <struts>
 7     
 8    <package name="ognlpackage" extends="struts-default">
 9            <action name="ognl" class="com.bie.ognl.OgnlAction">
10                <result name="success">ognl.jsp</result>
11            </action>
12    </package>
13    
14    
15 </struts>

5:最后书写ognl.jsp显示页面,用于显示信息,源码如下所示:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ taglib prefix="s" uri="/struts-tags"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>ognl显示信息的页面</title>
 9 
10 <style type="text/css">
11     .odd{background-color:pink;}
12     .even{background-color:yellow;}
13 </style>
14 </head>
15 <body>
16 
17 <h1>1:list显示信息</h1>
18 <table cellpadding="5" cellspacing="10">
19     <tr>
20         <th>编号</th>
21         <th>姓名</th>
22         <th>奇偶行</th>
23     </tr>
24     <s:iterator value="#request.list" var="user" status="us">
25     <tr class=<s:property value="#us.even?'even':'odd'"/>>
26         <td><s:property value="#user.id"/></td>
27         <td><s:property value="#user.name"/><br/></td>
28         <td><s:property value="#us.even" /></td>
29     </tr>
30     </s:iterator>
31 </table>
32 <h1>1:迭代map信息</h1>
33 <table cellpadding="5" cellspacing="10">
34     <tr>
35         <th>编号</th>
36         <th>编号2</th>
37         <th>姓名</th>
38         <th>奇偶行</th>
39     </tr>
40     <s:iterator value="#request.map" var="Muser" status="mu">
41     <tr class=<s:property value="#us.even?'even':'odd'"/>>
42         <td><s:property value="#Muser.value.id"/></td>
43         <!-- 迭代编号的两种方式 -->
44         <td><s:property value="#Muser.key"/></td>
45         <td><s:property value="#Muser.value.name"/><br/></td>
46         <td><s:property value="#mu.even" /></td>
47     </tr>
48     </s:iterator>
49 </table>
50 </body>
51 </html>

运行效果如下所示:

革命尚未成功,OGNL ko , go!!!

6:ValueStack, 即值栈对象(根元素的值存储在root中,非跟元素的值存储在context中)。

(1):值栈对象是整个struts数据存储的核心,或者叫中转站。

   (2):用户每次访问struts的action,都会创建一个Action对象、值栈对象、ActionContext对象;  然后把Action对象放入值栈中; 最后再把值栈对象放入request中,传入jsp页面。

   (3):(key: struts.valueStack); 开发者只需要通过ActionContext对象就可以访问struts的其他的关键对象。 (ActionContext是给开发者用的,便于学习与使用。)

 1 package com.bie.lesson09;
 2 
 3 
 4 import javax.servlet.http.HttpServletRequest;
 5 
 6 import org.apache.struts2.ServletActionContext;
 7 
 8 import com.opensymphony.xwork2.ActionContext;
 9 import com.opensymphony.xwork2.ActionSupport;
10 import com.opensymphony.xwork2.util.ValueStack;
11 
12 /** 
13 * @author  Author:别先生 
14 * @date Date:2017年9月23日 上午11:18:51 
15 *
16 * struts的数据流转,如何从后台到页面
17 */
18 public class OgnlAction extends ActionSupport{
19 
20     /**
21      * 
22      */
23     private static final long serialVersionUID = 1L;
24 
25     @Override
26     public String execute() throws Exception {
27         //获取值栈对象,方式一:
28         HttpServletRequest request = ServletActionContext.getRequest();
29         ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack");
30         
31         //获取值栈对象,方式二:
32         ActionContext ac = ActionContext.getContext();
33         ValueStack vs2 = ac.getValueStack();
34         
35         System.out.println(vs == vs2);
36         
37         return SUCCESS;
38     }
39 }

  (4)值栈的根元素和非根元素如何存储的关系:

 (5)值栈操作根元素和非根元素的如何操作(ActionContext.getContext() = #,取值的时候理解):

package com.bie.lesson09;


import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

/** 
* @author  Author:别先生 
* @date Date:2017年9月23日 上午11:18:51 
*
* struts的数据流转,如何从后台到页面
*/
public class OgnlAction extends ActionSupport{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    // 全局元素,根元素值
    private User user = new User(1, "tom");
    
    
    @Override
    public String execute() throws Exception {
        ActionContext ac = ActionContext.getContext();
        //映射数据
        //ac.getContextMap().put("request_data", "request_data");
        
        // 数据存储request
        @SuppressWarnings("unchecked")
        Map<String,Object> map = (Map<String, Object>) ac.get("request");
        map.put("request_data", "request_data");
        map.put("cn", "China");
        
        
        ac.getSession().put("session_data", "session_data");
        ac.getApplication().put("application_data", "application_data");
        
        // 二、值栈对象的存储数据的原理
        ValueStack vs = ac.getValueStack();
        
        /***************操作根元素的几种方法*****************/
        // 设置数据: 入栈
        // 栈顶
        //vs.getRoot().push(new User(2, "jack"));
        vs.push(new User(2, "jack"));
        // 移除栈顶元素
        vs.pop();
        
        
        // 如何存储?  map结构存储  
        vs.set("user1", new User(3, "张三"));
        vs.set("user2", new User(4, "李四"));
        
        
        System.out.println(vs);
        return SUCCESS;
    }
    
    
}

 (6):页面获取元素的方法:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
 4     "http://struts.apache.org/dtds/struts-2.0.dtd">
 5 
 6 <struts>
 7     <package name="ognlPackage" extends="struts-default">
 8             
 9         <action name="ognl" class="com.bie.lesson09.OgnlAction">
10             <result name="success">success.jsp?userName=${#request.request_data}</result>
11         </action>
12     </package>
13 
14 </struts>
15     
 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ taglib prefix="s" uri="/struts-tags"%>    
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>struts2 hello </title>
 9 </head>
10 <body>
11 
12 <h1>hello world struts2</h1>
13 
14 <h1>${requestScope.request_data }</h1>
15 <h1>${sessionScope.session_data }</h1>
16 <h1>${applicationScope.application_data }</h1>
17 
18 <!-- 页面: 必须要拿到ValueStack -->
19 <h1>根元素的值:</h1>
20 <s:property value="user.id"/><br/>
21 <s:property value="user.name"/><br/>
22 <s:property value="user.address"/><br/>
23 <s:property value="user.address.provice"/><br/>
24 <s:property value="user.address.city"/><br/>
25 
26 <br/><br/>
27 <!-- 非根元素的值 -->
28 <s:property value="#request.cn"/><br/>
29 <s:property value="#session.session_data"/><br/>
30 <s:property value="#application.application_data"/>
31 
32 <br/><br/>
33 <!-- 自动找request/session/application,找到后立刻返回 -->
34 <s:property value="#attr.cn"/><br/>
35 <s:property value="#attr.session_data"/><br/>
36 <s:property value="#attr.application_data"/><br/>
37 
38 <br/><br/>
39 <!-- 获取请求的参数数据 -->
40 <s:property value="#parameters.userName"/>
41      
42 
43 
44 <!-- struts的调试标签:可以观测值栈数据 -->
45 <s:debug></s:debug>
46 </body>
47 </html>
 1 package com.bie.lesson09;
 2 /** 
 3 * @author  Author:别先生 
 4 * @date Date:2017年9月23日 下午5:20:46 
 5 *
 6 *
 7 */
 8 public class Address {
 9 
10     private String provice;
11     private String city;
12     public String getProvice() {
13         return provice;
14     }
15     public void setProvice(String provice) {
16         this.provice = provice;
17     }
18     public String getCity() {
19         return city;
20     }
21     public void setCity(String city) {
22         this.city = city;
23     }
24     public Address(String provice, String city) {
25         super();
26         this.provice = provice;
27         this.city = city;
28     }
29     public Address() {
30         super();
31     }
32     
33     
34 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C语言及其他语言

【每日一题】问题 1209: 密码截获

Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码 进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一...

16420
来自专栏漏斗社区

ognl与struts2漏洞的学习

Struts2这个框架每年都会出现那么几个漏洞,不得不引起斗哥学习的兴趣。本期将从Struts2的一个罪魁祸首ONGL表达式开始介绍到S2-001漏洞的分析。S...

14420
来自专栏Ryan Miao

app令牌的一个token实现

app登陆验证不能使用session来判断了。然后查资料都说用令牌,没找到合适的方法,我的眼界太小。另外,越来越感觉基础的重要,比如,session是什么,我竟...

354120
来自专栏JavaEdge

Netty 源码深度解析(八) - 解码

就像很多标准的架构模式都被各种专用框架所支持一样,常见的数据处理模式往往也是目标实现的很好的候选对象,它可以节省开发人员大量的时间和精力。

24810
来自专栏码匠的流水账

聊聊storm trident的coordinator

storm-1.2.2/storm-core/src/jvm/org/apache/storm/trident/topology/MasterBatchCoor...

14440
来自专栏北京马哥教育

十分钟完成Bash 脚本进阶!列举Bash经典用法及其案例

? 前言:在linux中,Bash脚本是很基础的知识,大家可能一听脚本感觉很高大上,像小编当初刚开始学一样,感觉会写脚本的都是大神。虽然复杂的脚本是很烧脑,但...

39380
来自专栏PHP在线

PHP的几个常用加密函数

在网站的开发过程中,常常需要对部分数据(如用户密码)进行加密,本文主要介绍PHP的几个常见的加密函数

19260
来自专栏逍遥剑客的游戏开发

C++的反射和序列化

18720
来自专栏C语言及其他语言

【每日一题】问题 1209: 密码截获

题目描述 Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码 进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或...

28270
来自专栏difcareer的技术笔记

JNI实现源码分析【四 函数调用】正文0x01:dvmCallMethodV0x02:nativeFunc0x03: 何时赋值

有了前面的铺垫,终于可以说说虚拟机是如何调用JNI方法的了。JNI方法,对应Java中的native方法,所以我们跟踪对Native方法的处理即可。

11540

扫码关注云+社区

领取腾讯云代金券