Struts2之OGNL表达式
OGNL(Object-Graph Navigation Language的简称),对象图导航语言,它是一门表达式语言,除了用来设置和获取Java对象的属性之外,另外提供诸如集合的投影和过滤以及lambda表达式等。在Struts2中有大量的使用,本篇我们一起来研究一下OGNL表达式在Struts2中的使用。
首先是获取值栈中的普通属性,问题来了,哪些属性会被封装到值栈中呢?首先是我们在Action中设置的默认参数,其次是我们通过url地址传递给Action的参数,好了接下来我们做一下测试:首先是我们看一下我们的Action文件:
public class OJNL extends ActionSupport{ private String Name;//普通属性不设置默认值
private Integer age = 18;//为该属性添加默认值 public String getName() {
return Name;
} public void setName(String name) {
Name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} @Override
public String execute() throws Exception {
return SUCCESS;
} }
按照我们刚刚的介绍,name、age两个属性将会被添加到值栈中,我们接下来就看一下我们如何在jsp页面获得这两个属性值:
<ol>
<li>访问值栈中的普通属性:name:<s:property value="name" /></li>
<li>访问值栈中的普通属性:age:<s:property value="age" /></li>
<li>访问值栈中的普通属性:password:<s:property value="password" /></li>
<li><s:debug></s:debug></li>
</ol>
url请求:<a href="http://localhost:8080/Struts/ognl?name=hpugs&password=123456">OGNL表达式</a>
请求结果:
值栈中的数据内容:
看完了如何从值栈中获取普通属性,下面我们看一下如何从值栈中获取对象属性。通过获取对象属性我们一起回顾一下,如何给对象类型传递参数:1、url中对象名.属性名传参;2、实现ModelDriven<T>接口;这些不是今天的重点,如果你有不懂的地方,请查阅之前的分享,接下来回归正题,当我们通过上面的形式传递参数到对象后,值栈中是不是就会出现这个对象?我们是不是就可以通过类名.属性名来获去参数?如果你和我一样有疑惑,下面我们就一起通过代码实例,简单测试一下。下面我们分几种情况来看一下我们的值栈中对象的创建情况:
第一种:
访问值栈中的对象的普通属性(地址栏传参),首先创建一个User对象类:
public class User {
private int age; public User(){ } public User(int age){
this.age = age;
} @Override
public String toString() {
return "User [age=" + age + "]";
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} }
这里为什么要添加构造方法,在接下来的测试中我们会重点提这一点,大家可以先按上面的内容创建一下类对象。有了类对象,接下来就是我们Action对象了:
public class OGNL extends ActionSupport { private User user;//声明一个User对象 public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} @Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
} }
写好了上面的内容,我们知道要为Action添加参数,我们需要在地址栏通过类名.属性名来传递,我们的url请求:
<a href="http://localhost:8080/Struts/ognl?user.age=24">OGNL表达式</a>
我们的jsp页面获取OGNL代码:
<ol>
<li>访问值栈中的对象的普通属性(地址栏传参):user.age:<s:property value="user.age" /></li>
<li><s:debug></s:debug></li>
</ol>
访问结果:
第二种:
访问值栈中的对象的普通属性(对象中设置默认值,地址栏不传参),与上面不同的地方是,我们不再通过地址栏传递参数到Action,我们直接在对象中为age添加默认值,我们的User类:
public class User {
private int age = 18; public User(){ } public User(int age){
this.age = age;
} @Override
public String toString() {
return "User [age=" + age + "]";
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} }
我们的Action与上面的一致,这里就不在增加篇幅了,既然我们已经在User对象里面为age属性添加了默认值,那么我们就不在通过url传递参数,我们来测试一下,前台jsp是否可以从值栈中获取到age属性:
我们的url请求:
<a href="http://localhost:8080/Struts/ognl">OGNL表达式</a>
我们的jsp页面处理:
<ol>
<li>访问值栈中的对象的普通属性(对象中设置默认值,地址栏不传参):user.age:<s:property value="user.age" /></li>
<li><s:debug></s:debug></li>
</ol>
测试结果:
小伙伴们是不是不淡定了,我们明明设置了默认值,为什么值栈中是NULL呢?大家想一想第一种,当我们通过Url将user.age传递到Action后,Action会为我创建一个User对象,并将age属性传递过去,而现在我们不再通过url传递user.age参数了,所以Action也就不再为我们创建User对象,所以值栈中user == null
第三种:
对于第二种情况,你是不是和我一样有疑惑,难得我们必须通过Url才能使Action为我们创建user对象吗?答案是肯定的。如何实现呢?既然是Action没有为我们实例化user对象,我们是不是可以手动在Action中实例化user对象,下面我们做一下测试,修改一下我们的Action类:
public class OGNL extends ActionSupport{ private User user = new User(); public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} @Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
} }
接下来我们再次运行我们的项目,看一下值栈中的数据:
这样值栈中就有了user对象。
第四种:
看到第三种你是不是和我一样有一个小疑问,Action是如何为我们实例化user对象的,其实明显了,就是通过调用User类的无参构造方法,当然我们这里也简单做下测试。这里我们一起回忆一下关于java中类的构造方法的知识,首先构造方法,方法名要与类名一致,其次方法没有返回值。我们还知道,当我们没有为类添加构造方法时,系统默认为我们实现一个无参构造方法,当我们添加了有参构造方法后,系统将不再为我们添加默认构造方法。这里我们就将User类的构造方法去掉,保留有参构造方法:
public class User {
private int age = 12; public User(int age){
this.age = age;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} }
我们的Action配置与第一种一摸一样,这里就不再添加篇幅,下面直接看结果:
关于值栈中对象的普通属性的获取就和大家先聊到这里
上面我们介绍了单个对象属性获取,下面我们介绍一下通过一个对象去获取另一个对象的属性,比如有一只猫(加菲),有一个好朋友(欧第),我们通过加菲拿到欧弟的属性:
首先我们先创建两个对象,Cat.class、Dog.class:
public class Cat { private Dog friend; public Dog getFriend() {
return friend;
} public void setFriend(Dog friend) {
this.friend = friend;
} }
public class Dog {
private String name; public Dog() {
} public Dog(String name) {
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Dog [name=" + name + "]";
} }
下面就是我们的Action了,我们在Action中声明一个Cat对象:
public class OGNL extends ActionSupport { private Cat cat; public Cat getCat() {
return cat;
} public void setCat(Cat cat) {
this.cat = cat;
} @Override
public String execute() throws Exception {
return SUCCESS;
}
}
接下来我们就通过Url为我们的Dog对象起一个名字:欧弟
<a href="http://localhost:8080/Struts/ognl?cat.friend.name=欧弟">OGNL</a>
我们的jsp参数接收方式;
<ol>
<li>访问值栈中的对象的普通属性:cat.friend.name:<s:property value="cat.friend.name" /></li>
<li><s:debug></s:debug></li>
</ol>
访问结果:
下面我们接上面的内容,一起来探讨一下,如何访问值栈中的对象的普通方法,一种:值栈中基本方法(length()这类方法);一种Action中对象的普通方法。
这里我们在Cat类里面添加一个Eat()方法,用于jsp页面进行调用:
public class Cat { private Dog friend; public Dog getFriend() {
return friend;
} public void setFriend(Dog friend) {
this.friend = friend;
} public String Eat(){
return "猫爱吃鱼";
}
}
下面我们看一下我们的jsp中的参数处理:
<ol>
<li>访问值栈中的对象的普通属性:cat.friend.name:<s:property value="cat.friend.name" /></li>
<li>访问值栈中的对象的普通方法:cat.friend.name.length():<s:property value="cat.friend.name.length()" /></li>
<li>访问值栈中的对象的普通方法:cat.Eat():<s:property value="cat.Eat()" /></li>
<li><s:debug></s:debug></li>
</ol>
下面看一下处理结果:
接下来我们一起来探讨一下如何访问Action中的静态方法和静态属性,这次我先来看一下jsp参数的处理模块:
<ol>
<li>访问静态属性:YEAR:<s:property value="@com.edu.action.OGNL@YEAR" /></li>
<li>访问静态方法:GetDate():<s:property value="@com.edu.action.OGNL@GetDate()" /></li>
<li>访问Max的静态方法:max(1,1):<s:property value="@@max(1,1)" /></li> <li>访问普通对象的构造方法:new User(8):<s:property value="new com.edu.model.User(8)" /></li>
<li><s:debug></s:debug></li>
</ol>
由此来设计我们的User类:
public class User {
private int age; public User(int age){
this.age = age;
} @Override
public String toString() {
return "User [age=" + age + "]";
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} }
然后是我们的Action类:
public class OGNL extends ActionSupport{ //静态属性
public static final Date YEAR = new Date(); //静态方法
public static String GetDate(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
return simpleDateFormat.format(new Date());
} @Override
public String execute() throws Exception {
return SUCCESS;
} }
URL请求地址:
<a href="http://localhost:8080/Struts/ognl">OGNL表达式</a>
最后的处理结果:
最后是关于OGNL操作List、Set、Map的知识,这里就不再一一展开详述。这路用到两个类:User和Dog,这两个类的没有什么特别需要说明的内容,只是两个基本的对象类,这里不再展示,我直接从Action类开始:
public class OGNL extends ActionSupport { private List<User> users = new ArrayList<User>(); private Set<Dog> dogs = new HashSet<Dog>(); private Map<String, Dog> dogMap = new HashMap<String, Dog>(); //每次访问Action都会执行,放置一些类的初始化操作
public OGNL(){
users.add(new User(1));
users.add(new User(2));
users.add(new User(3)); dogs.add(new Dog("dog1"));
dogs.add(new Dog("dog2"));
dogs.add(new Dog("dog3")); dogMap.put("dog11", new Dog("dog11"));
dogMap.put("dog22", new Dog("dog22"));
dogMap.put("dog33", new Dog("dog33"));
} public List<User> getUsers() {
return users;
} public void setUsers(List<User> users) {
this.users = users;
} public Set<Dog> getDogs() {
return dogs;
} public void setDogs(Set<Dog> dogs) {
this.dogs = dogs;
} public Map<String, Dog> getDogMap() {
return dogMap;
} public void setDogMap(Map<String, Dog> dogMap) {
this.dogMap = dogMap;
} @Override
public String execute() throws Exception {
return SUCCESS;
} }
通过Action的无参构造方法,初始化我们List\Set\Map,接下来我们一起看一下jsp中参数的处理:
第一种:List类型
<ol>
<li>访问List:<s:property value="users" /></li>
<li>访问List中某个元素users[1]:<s:property value="users[1]" /></li>
<li>访问List中某个属性的集合users.{age}:<s:property value="users.{age}" /></li>
<li>访问List中某个属性集合中的特定值users.{age}[2]:<s:property value="users.{age}[2]" /></li>
<li><s:debug></s:debug></li>
</ol>
结果页面:
通过值栈的信息结合jsp页面的处理内容,List的结果处理没有太多难处。
第二种:Set类型
<ol>
<li>访问Set:<s:property value="dogs" /></li>
<li>访问Set中的某个元素:<s:property value="dogs[1]" /> | <span style="color:red">set中的数据是无序的,所以没办法获取set中的具体元素</span></li>
</ol>
结果页面:
和List的区别在于,List中可以根据索引找到集合中的数据,而Set由于元素无序且不能重复,故不能通过索引取得值。
第三种:Map类型
<ol>
<li>访问Map:<s:property value="dogMap" /></li>
<li>访问Map某个元素:<s:property value="dogMap.dog11" />|<s:property value="dogMap.dog22" />|<s:property value="dogMap.dog33" /></li>
<li>访问Map所有Key:<s:property value="dogMap.keys" /></li>
<li>访问Map所有Value:<s:property value="dogMap.values" /></li>
<li>访问Map容器大小:dogMap.size<s:property value="dogMap.size" />|users.size<s:property value="users.size" />|dogs.size<s:property value="dogs.size" /></li>
<li>访问Map容器大小:dogMap.size()<s:property value="dogMap.size()" />|users.size()<s:property value="users.size()" />|dogs.size()<s:property value="dogs.size()" /></li>
</ol>
结果页面:
Map中数据都是以key-value的形式保存的,当需要通过key得到指定的value时,我们只需要通过Map对象.key即可拿到值。对于获得List、Set、Map中的数据总数可以通过.size或.size()来获取。
下面我们来一起看一下关于集合投影和过滤的内容,这里先要解释三个符号:'?':过滤;'^':开头;'$':结尾,下面我们来看一下在OGNL中的具体使用:
<ol>
<li>投影(过滤):<s:property value="users.{?#this.age == 1}.{age}" />-----?:过滤</li>
<li>投影(过滤):<s:property value="users.{?#this.age == 1}.{age}[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>
</ol>
结果页面:
1、解释一下users.{?#this.age == 1}.{age}:过滤users中age==1的对象,将其age属性组成一个数组
2、users.{?#this.age == 1}.{age}[0]:过滤users中age==1的对象,将其age属性组成一个数组,取数组中的第一个age元素
3、users.{^#this.age > 1}.{age}:过滤users中age>1的对象,将其age属性组成一个数组,取出数组中的第一个age元素
4、users.{$#this.age > 1}.{age}:过滤users中age>1的对象,将其age属性组成一个数组,取出数组中的最后一个age元素
5、users.{$#this.age > 1}.{age} == null:过滤users中age>1的对象,将其age属性组成一个数组,最后判断数组是否为空
Struts2之OGNL表达式的更多相关文章
- Struts2的OGNL表达式语言
一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...
- 初窥struts2(二)OGNL表达式
Struts2总结 Struts2完整的处理流程: 1 客户端发送请求,交给struts2控制器(StrutsPrepareAndExecuteFilter). 2 Filter控制器进行请求过滤 ...
- struts2 与 OGNL 表达式,jsp中 利用ognl 在valuestack中取值
在Struts2中,一个请求在终于到达Action的方法之前,Action对象本身会被压入ValueStack(实际上就是放到ValueStack的CompoundRoot中),所以Action对象是 ...
- struts2(四) ognl表达式、值栈、actionContext之间的关系
今天来说说ognl表达式在struts2中的运用. --wh 一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任 ...
- Struts2之 OGNL表达式和值栈
技术分析之OGNL表达式概述(了解) 1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写 * 所谓对象图,即以任意 ...
- struts2:OGNL表达式,遍历List、Map集合;投影的使用
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存 ...
- struts2:OGNL表达式之#、%、$符号运用
1. OGNL表达达符号"#" 1.1 #用于访问OGNL上下文和Action上下文,#相当于ActionContext.getContext() 注意:当系统创建了Action实 ...
- java之struts2之OGNL表达式
struts2推荐使用ognl表达式 ognl: object graph navigation language 对象导航图语言 如:school.teacher.address="北京& ...
- Struts2中OGNL表达式的用法
今天分享的是Struts2框架中的一种ognl表达式语言,主要分两个目标去学习 1.理解struts2传值的优先级 2.ognl与el的区别 一:ognl表达式语言简介 OGNL的全称是O ...
随机推荐
- window下redis的安装
1.使用phpinfo()函数查看PHP的版本信息,这会决定扩展文件版本2.根据PHP版本号,编译器版本号和CPU架构,选择php_redis-2.2.5-5.5-ts-vc11-x86.zip和ph ...
- tbl.js div实现的表格控件,完全免费,不依赖jquery
html上现在有比较好用的表格控件是datatable,但是编辑.按钮等部分是收费的,只有基础功能免费.而且尺寸发生变化时需要手工刷新等繁琐操作较多.所以我开发一个免费的供大家使用. 本项目已用于&q ...
- JAVA中的访问修饰符和包
一.JAVA访问修饰符 访问修饰符,用来控制类中成员的可见性 有四个访问修饰符,分别是:default,private,public,protected 1.default(默认):默认权限,不用写的 ...
- java 多线程之卖票两种方式
1.通过extends Thread /* 需求:简单的卖票,多个窗口同时买票 (共用资源) 创建线程的第二种方式:实现Runnable接口 步骤: 1,定义类实现Runnable接口 2,覆盖/重写 ...
- php 引入文件 include 和require
php 如何引用文件? 先建一个php 文件,php文件名要和所建的类名相同, 然后直接在php 中用include("")/include"" 和requir ...
- Javascript面对对象. 第四篇
原型模式创建对象也有自己的缺点,它省略看构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的. 而原型最大的缺点就是它优点,那就是共享. 原型中所有属性是被很多实例共享的,共享对于函数非常合 ...
- java初级开发程序员(第六单元)
1.for循环结构: 循环结构分为四个部分. >初始部分:设置循环的初始状态,如设置记录循环次数的变量i为0. >循环体:重复执行的代码,即输出“好好学习,天天向上!”. >迭代部分 ...
- linux下php调试工具xdebug安装配置
xdebug简介 Xdebug是php的一款调试工具,是基于zend的一个扩展,可以用来跟踪,调试和分析PHP程序的运行状况.如变量,函数调试,性能监测,代码覆盖率等 xdebug安装 1.下载xde ...
- dev控件chart简单实现多图例,双曲线,双柱图,曲线与柱图
1.效果图 2.数据源代码: ; i < ; i++) { == ) { dt1.Rows.Add( * i); dt2.Rows.Add( * i+); } else { dt1.Rows.A ...
- 基于keepalived搭建MySQL高可用集群
MySQL的高可用方案一般有如下几种: keepalived+双主,MHA,MMM,Heartbeat+DRBD,PXC,Galera Cluster 比较常用的是keepalived+双主,MHA和 ...