Struts2之OGNL的使用

2018-05-10 18:59:37 浏览数 (1)

OGNL的使用

  • 本人独立博客https://chenjiabing666.github.io

OGNL简介

  • OGNI是一种对象图导航语言(object graphics navigation language) ,这也是一种表达式语言,这个和EL表达式一样,但是EL表达式只能在JSTL标签库中使用,这个OGNL只能在struts标签库中使用。

值栈(valueStack)

  • 值栈就是存储Action的信息,包括其中定义的成员变量和其他的一些自己的属性,比如error,fieldError,如果想要让action中属性在值栈中显示或者获取,一定要为这些属性设置get,set方法
  • 值栈是存储的action的栈,同时可以存储多个action,先执行的先进栈
  • 值栈中的元素是根元素,访问值栈中的元素不需要使用#(#是访问非根元素的值,比如#session.username)
  • 在jsp页面可以使用struts标签库<s:debug/>,查看值栈中的内容

实验

  • 我们新建一个Action类,用表单传递数据请求action,最后action跳转到success.jsp页面,我们在success.jsp使用<s:debug>查看此时值栈中的数据
    • 其中的属性必须要有get,set方法
  • LoginAction
代码语言:javascript复制
//实现ModelDriven接口<>指定的泛型为JavaBean类
public class LoginAction extends ActionSupport {
    private User user;
    private String tips;
​
    public String getTips(){
        return tips;
    }
    public void setTips(String tips){
        this.tips=tips;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
​
    @Override
    public String execute() {
        System.out.println("执行execute方法");
        System.out.println(this.getUser().getName() "------" this.getUser().getPassword());
        return SUCCESS;
    }
​
  • success.jsp页面
    • 其中要引用struts2的标签库
代码语言:javascript复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <s:debug></s:debug>
</body>
</html>
​
  • 此时我们可以看到在值栈中有个user属性,并且有LoginAction

常量

  • 我们现在先接触一下<s:property value="">标签,struts2中的标签在后面再详细讲解,这个标签的意思是输出属性的值
    • 这个标签中的value属性填写的是OGNL表达式,如果我们要输出一个常量,那么我们必须使用单引号
    • 引用struts2中的标签库<%@ taglib prefix="s" uri="/struts-tags" %>

字符常量

  • 如果我们仍然使用上面的实例,但是我们要在success.jsp页面中使用OGNL使用显示表单传递过来的值,其中我们还输出自己的一个常量字符串
  • success.jsp
代码语言:javascript复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
​
    <h1><s:property value="user.name" default="如果为null,输出这个字段"/></h1>
    <h1><s:property value="user.password" default="如果为null,输出这个字段" /></h1>
​
    <h1>输出一个字符串常量: <s:property value="'jack'"/></h1>
    <s:debug></s:debug>
</body>
</html>

数值常量

  • int 1,2,3
  • double 1.24d或者1.24
  • float 1.23f
  • long 122l 最后一个是字母l
  • BigDecimal 123b
  • BigInteger 123h
  • 在其中直接输出即可:<s:property value="1"/>

布尔常量

  • 直接输出即可 <s:property value="true"/>

总结

  • 当需要输出一个字符串常量的时候,一定要使用单引号,否则就会默认的将其作为OGNL表达式,输出的就为空

集合list

  • OGNL中的list相当于数组,其中存放的可以是任意类型的数据
  • 读取的时候直接使用数组的形式读取即可,使用索引读取即可
  • 我们的创建形式是使用<s:set>标签,因此这个变量不是值栈中的,需要使用#
代码语言:javascript复制
    <!-- 创建list -->
    <s:set var="list" value="{1,2,3,'jack',true}"></s:set>
    <s:property value="#list[0]"/><br>
    <s:property value="#list[4]"/>

Map

  • 使用#{}的形式创建,其中存放的是键值对(key-value)的形式
  • 读取的方式有两种
    • map['key']
    • map.key
代码语言:javascript复制
    <s:set var="map" value="#{'name':'jack','age':22}"></s:set>
    <s:property value="#map['name']"/>
    <s:property value="#map.age"/>

访问action中的属性值

  • action都是存放在值栈中,我们可以使用OGNL读取值栈中的数据
  • 使用上面的LoginAction类,我们通过表单提交到这个LoginAction中,跳转到success.jsp页面中,那么我们就可以在success.jsp页面中访问LoginAction属性的值(前提是属性必须有get,set方法)
  • LoginAction中的属性是一个User对象,那么我们既可以获取这个User对象,之后在获取User对象中的数据了,这个相当于链式操作,前提还是有get,set方法
代码语言:javascript复制
    <!-- 这里的user一定要和LoginAction中的成员变量User的对象字段相同 -->
    User对象中的name属性:<s:property value="user.name"/>
    User对象中的age属性:<s:property value="user.age"/>

操作符

#

  • 值栈中的的属性称为是根属性,#访问的是非根属性,就不是值栈中的值,比如#session.username 相当于调用ActionContext.getContext.getSession.getAttribute("username")
  • 创建Map
  • 过滤和投影

$符号

  • 在国际化文件中使用OGNL表达式,例如年龄必须在到​{max}之间
  • 在Struts配置文件中使用OGNL表达式,例如两个Action之间进行跳转,并且附带参数

% 符号

  • 当标签的属性为字符串类型时,计算OGNL表达式的值。
代码语言:javascript复制
<s:url value="#map.name"/>
<br>
<s:url value="%{#map.name}"/>

大括号 {}

  • 用来创建一个Map,其中存放的是键值对
  • 创建一个list集合
代码语言:javascript复制
<s:set var="map" value="#{'name':'jack','age':22}"></s:set>
<s:property value="#map['name']"/>

in ,not in

  • 判断某一个值是否存在一个集合中,返回的是布尔值
  • 不过经过自己测试,只有数字类型的可以判断出来,字符串不能判断出来,如果哪位能够测出来,和我说说原因
代码语言:javascript复制
<!-- 创建一个集合list -->
    <s:set var="list" value="{1,2,3,'jack','Tom'}"></s:set>
    <s:property value="1 in #list"/><br>
    <s:property value="1 not in #list"/><br>
    <!-- 没有结果 -->
    <s:property value=" 'jack' in #list"/><br>

  • 这个和java是一样的,如果两个整数相加就执行整数相加,如果字符串相加就拼接
代码语言:javascript复制
    <s:property value="2 3"/>
    <s:property value="'ce' 22"/>

集合的伪属性

集合的伪属性是用来代替java集合API的方法的属性,比如迭代器的使用

  • List
    • list.iterator
    • list.size
  • Set
    • set.iterator
    • set.isEmpty
  • Map
    • map.keys (map.keySet)
    • map.values (map.values)
  • Iterator
    • Iterator.next
    • Iterator.hasNext
  • Enumeration
    • enum.next
    • enum.hasNext
代码语言:javascript复制
    <%--创建列表 --%>
    <s:set var="list" value="{1,'陈加兵'}"></s:set>
​
    <%-- 创建Map --%>
    <s:set var="map" value="#{'one':'陈加兵','tow':'郑元梅'}"></s:set>
​
    <%-- 创建数组 --%>
    <s:set var="number" value="new String[]{'aaa','bbb','ccc']"></s:set>
​
​
    <%--  获取list的迭代器对象 --%>
    <s:set var="iter" value="#list.iterator"></s:set>
    list的大小:<s:property value="#list.size"/>
    <s:if test="#iter.hasNext">
        list中的第一个元素的值:<s:property value="#iter.next"/>
    </s:if>
    <hr>
​
    <%-- #map.keys返回的是set类型,然后使用迭代器输出即可 --%>
    <s:property value="#map.keys.iterator.next" default="NULL"/>
    <s:property value="#map.values"/>

投影

  • 在OGNL中,投影是对一个集合中对每一个元素调用相同的方法,或者抽取相同的属性,并将一个结果保存为一个新的集合。
  • 下面的例子是将集合list中的元素转换成字符串
代码语言:javascript复制
    <%--创建列表 --%>
    <s:set var="list" value="{1,'陈加兵'}"></s:set>
    <%-- 这个{#}首先会取list中的每一个元素然后赋值给tihs,接着调用toString方法转换为字符串 --%>
    <s:property value="#list.{#this.toString()}"/>

选择

  • 在OGNL中使用表达式从集合中选择某一些元素,并将这些元素保存到新的集合中
代码语言:javascript复制
    <%--创建列表 --%>
    <s:set var="list" value="{1,2,3}"></s:set>
​
    <%-- 选取大于2的元素组成一个新的集合 --%>
    <s:property value="#list.{?#this>2}"/>

[N]语法

  • 我们知道一次请求值栈中可以存放两个或者多个action(只需要设置result跳转类型为chain即可完成在action之间的跳转),那么我们一般取值栈中的值默认是获取栈顶的action,但是如果有多个action呢,此时我们需要获取其他action中的数据,这下就要用到[N]语法了
  • [N].propertyName可以用来指定从值栈中的从上向下数位置N的action的属性值,N从事0开始的。

实现

  • 假设我们有两个Action,一个是SimpleAction,一个是LoginAction(上面的,有一个属性为user),我们在在配置的时候,发出请求给SimpleAction,之后跳转到LoginAction(result的type类型为chain即可),之后跳转到success.jsp,那么此时的值栈中的action就有两个了,栈顶的是SimpleAction,第二个是LoginAction。
    • 我们想要获取LoginAction属性user的值,在值栈中的位置是第二个,那么此时使用[1].propertName
代码语言:javascript复制
    User对象中的name:<s:property value="[1].user.name"/>
    User对象中的age:<s:property value="[1].user.age"/>

top 语法

  • 我们知道[N]语法中,如果想要访问栈顶的action属性使用[0].propertyName,我们也可以使用top,直接top.propertyName即可

Struts2的命名对象

  • 这些对象都不是值栈中的数据,因此需要使用#来获取
  • parameters用来访问请求参数,比如#parameters.name, # parameters [‘name’]相当与request.getParameters(“name”)
  • request用来访问request的属性,比如#request.name或者# request [‘name’] 相当于request,getAttrubute(“name”)
  • session用来访问session属性,例如 #session.name或者#session[‘name’]相当于 session.getAttribute(“name”)
  • application用来访问application属性,比如:#application.name相当于application.getAttribute(“name”)
  • attr用来访问PageContext,如果PageContext不可用,则一次搜索request,session,application对象

0 人点赞