OGNL

一:OGNL简介

OGNL的全称是Object  Graph  Navigation  Language即对象导航语音。它是一个开源项目,工作在视图层,用来取代页面中的java脚本。简化数据库的访问操作。

OGNL是一种强大的技术,被集成在Struts 2框架中用来帮助实现数据的传输和类型转换。

表达式语音:在视图层将数据从页面传入框架和从框架获取输出数据生成页面的过程,OGNL提供了一个简单的语法,将表单与Struts 2标签与java各种类型的数据绑定起来,列如:

<input  type=”text”  name=”user.name”/>的输入对应Action类中User对象的name属性。

类型转换器:每次数据流入和流出框架,页面中的字符串类型的数据和java数据类型之间都会发生转换。

一、OGNL全称是Object Graph Navigation Language,即对象导航图语言

OGNL在框架中主要做两件事情:表达式语言和类型转换器

二:OGNL在框架中的作用以及数据的流入流出:


二、ValueStack值栈

定义:是内存中的一块空间,栈和堆之外的空间,它具有栈的特征,可以存放多个对象,如果存放多个对象,他们是按照先后顺序压入堆栈的。框架在处理每个请求时,都会创建该请求对应的运行环境,这时会创建值栈和请求对应的Action实例,并将Action实例压入值栈中


三、实现思路

可通过单列(Root)、双列(Context)集合获取ValueStack

单列集合:

创建Action类继承自ActionSupport,首先通过ServletActionContext获取到request对象,其次创建UserInfo对象,通过ValueStack对象的getRoot方法拿到UserInfo对象info

public class ValueStackAction extends ActionSupport {

@Override

public String execute() throws Exception {

HttpServletRequest request = ServletActionContext.getRequest();

ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack");

UserInfo info = new UserInfo();

info.setUsername("呵呵");

info.setPassword("12345");

vs.getRoot().add(info);

return SUCCESS;

}

index.jsp页面进行取数据:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">

<title>My JSP 'index.jsp' starting page</title>

</head>

<body>

valueStack

<s:property value="username"/>

<s:debug></s:debug>

</body>

</html>


双列集合:

index.jsp页面:需注意的是双列集合通过#获取数据

使用ognl表达式:

1)“#”符号有三种用途

a、访问非根对象(struts中值栈为根对象),eg:OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性:

名称   作用域

eg:

1-1)parameters :包含当前HTTP请求参数的Map

#parameters.id[0]=>作用相当于request.getParameter("id")

1-2)request:包含当前HttpServletRequest的属性(attribute)的Map

#request.userName=>作相当于于request.getAttribute("userName");

1-3)session:包含当前HttpSession属性(attribute)的Map

#session.userName=>session.getAttribute("userName");

1-4)application:包含当前应用的ServletContext的属性(attribute)的Map

#application.userName=>application.getAttribute("userName");

三:数据的流出

当Action 完成业务处理后,最终会返回一个结果,并生成页面。最关键的地方在于在处理请求的过程中,所有业务数据对象都保留在值栈中值栈充当了一个容器,,通过它在框架的各个地方都可以随时访问这些业务对象,在生成页面的过程中,页面标签都可以访问值栈,并通过OGNL表达式获取对象的值。

四:Value Stack值栈

1.什么是值栈:

值栈就是框架创建的一个存储区域,用来保存Model对象,它具有栈的特性,可以存放多个对象,,但是要按照先后顺序压入栈的。框架处理每个请求时,都会创建对应的运行环境,这是会创建值栈和请求对应的Action 实例,并将每个Action实例压入值栈中。值栈是一个虚拟对象,它可以暴露它所包含的所有对象的的属性,就好像这些属性是它自己的一样。

2.OGNL优先使用:

OGNL访问值栈时从它的上往下访问不管值栈是否有关重复的靠近值栈最上面的属性都

会被优先使用。

五:类型转换器

  1. 为什么要使用类型转换器:

在基于HTTP协议的web应用中,客户端请求的所有内容,均以文本编码的形式传入到服务器端,但服务器端的编程语言,有着丰富的数据类型,如int,boolean,Date及自定义类型等,因此当这些参数进入应用程序时,它们必须转换为合适的服务器端编程语言的数据库类型。

  1. 内置类型转换器:

(1.)Stirng:将int,long,double,Boolean,String类型的数组,或java.util.Date类型转换为字符串。

(2.)boolean/Boolean:在字符串和布尔类型之间进行类型转换。

(3.)char/Character:在字符串和字符串之间进行转换。

(4.)int /Integer,float/Fload,long/Long,double/Doubl:在字符串和数值之间进行转换。

(5.)Date:在字符串和日期类型之间进行转换,具体输入/输出格式与当前的Local相关。

(6.)数组和集合:在字符串数组和数组对象,集合对象之间转换。

1.原始类型和包装类

示例如下:

public class ShowOrginalAndJavaBeanAction extends ActionSupport {

private User user;

private String msg;

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}

public String getMsg() {

return msg;

}

public void setMsg(String msg) {

this.msg = msg;

}

public String execute(){

User user=new User();

user.setName("accp");

user.setAge(22);

Adderss address=new Adderss();

address.setGj("中国");

address.setCity("北京");

address.setStreet("城府路");

//user.setAdderss(adderss);

setMsg("展示原始类型和JavaBean");

return SUCCESS;

}

}

页面展示代码如下:

<body>

<h2>直接量:</h2>

<s:property value="msg" /><br>

姓名:<s:property value="user.name" /><br/>

年龄:<s:property value="user.age" /><br/>

国家:<s:property value="user.address.gj" /><br/>

城市:<s:property value="user.address.city" /><br/>

街道:<s:property value="user.address.street" /><br/>

</body>

  1. 多值类型请求参数的处理

(1.)数组的方式:

public class ArrayAction extends ActionSupport{

private String[] hobbies;

private Double[] numbers=new Double[3];

public String[] getHobbies() {

return hobbies;

}

public void setHobbies(String[] hobbies) {

this.hobbies = hobbies;

}

public Double[] getNumbers() {

return numbers;

}

public void setNumbers(Double[] numbers) {

this.numbers = numbers;

}

public String execute(){

for (int i = 0; i < hobbies.length; i++) {

System.out.println("数组第:"+i+"元素,为"+hobbies[i]);

}

System.out.println();

for (int i = 0; i < numbers.length; i++) {

System.out.println("第"+i+"个元素,为"+numbers[i]);

}

return SUCCESS;

}

}

页面显示代码如下:

<body>

<h2>数组:</h2>

<s:form action="arrayAction" method="post" />

<s:textfield name="hobbies" label="爱好:" />

<s:textfield name="hobbies" label="爱好:" />

<s:textfield name="hobbies" label="爱好:" />

---------------------------

<s:textfield name="numbers[0]" label="数字:" />

<s:textfield name="numbers[1]" label="数字:" />

<s:textfield name="numbers[2]" label="数字:" />

<s:submit value="提交"></s:submit>

</body>

(2.)集合的方式:

public class ListAction extends ActionSupport{

private List hobbies;

private List<Integer> numbers;

private List<User> users;

public List getHobbies() {

return hobbies;

}

public void setHobbies(List hobbies) {

this.hobbies = hobbies;

}

public List<Integer> getNumbers() {

return numbers;

}

public void setNumbers(List<Integer> numbers) {

this.numbers = numbers;

}

public List<User> getUsers() {

return users;

}

public void setUsers(List<User> users) {

this.users = users;

}

public String execute1(){

for (int i = 0; i < hobbies.size(); i++) {

System.out.println("数组第:"+i+"元素,为"+hobbies.get(i));

}

System.out.println();

for (int i = 0; i < numbers.size(); i++) {

System.out.println("第"+i+"个元素,为"+numbers.get(i));

}

System.out.println();

for (int i = 0; i < numbers.size(); i++) {

System.out.println("第"+i+"个元素,为"+users.get(i).getName());

}

return SUCCESS;

}

}

页面显示代码如下:

<body>

<h2>数组:</h2>

<s:form action="listyAction" method="POST" />

<s:textfield name="hobbies" label="爱好:" />

<s:textfield name="hobbies" label="爱好:" />

<s:textfield name="hobbies" label="爱好:" />

---------------------------

<s:textfield name="numbers[0]" label="数字:" />

<s:textfield name="numbers[1]" label="数字:" />

<s:textfield name="numbers[2]" label="数字:" />

---------------------------

<s:textfield name="user.name" label="姓名:" />

<s:textfield name="user.name" label="姓名:" />

<s:textfield name="user.name" label="姓名:" />

<s:submit value="提交"></s:submit>

</body>

六:自定义转换器:

  1. 创建自定义转换器
  2. 配置自定义转换器
  3. 创建和配置日期转换器

示例如下:在此之前先创建一个这样的类:

public class DateAction extends ActionSupport{

private String currentDate;

public String getCurrentDate() {

return currentDate;

}

public void setCurrentDate(String currentDate) {

this.currentDate = currentDate;

}

public String dates(){

return SUCCESS;

}

}

然后在创建:

public class DateConverter extends StrutsTypeConverter {

private final DateFormat[] dfs={

new SimpleDateFormat("yyyy年MM月dd日"),

new SimpleDateFormat("yyyy-MM-dd"),

new SimpleDateFormat("MM/dd/yy"),

new SimpleDateFormat("yyyy.MM.dd"),

new SimpleDateFormat("yyyyMMdd"),

new SimpleDateFormat("yyyy/MM/dd")

};

/*

* 将指定格式的字符串转换为日期类型

* (non-Javadoc)

* @see org.apache.struts2.util.StrutsTypeConverter#convertFromString(java.util.Map, java.lang.String[], java.lang.Class)

*/

@Override

public Object convertFromString(Map context, String[] values, Class toType) {

// TODO Auto-generated method stub

String dateStr=values[0]; //获取日期的字符串

for (int i = 0; i < dfs.length; i++) { //遍历日期支持的格式进行转换

try {

return dfs[i].parse(dateStr);

} catch (Exception e) {

// TODO: handle exception

continue;

}

}

//如果遍历完毕后仍没有转换成功,表明出现转换异常

throw new TypeConversionException();

}

/*

* 将日期格式转换为指定字符串

* (non-Javadoc)

* @see org.apache.struts2.util.StrutsTypeConverter#convertToString(java.util.Map, java.lang.Object)

*/

@Override

public String convertToString(Map context, Object object) {

// TODO Auto-generated method stub

Date date=(Date)object;

//输出的格式是yyyy--MM-dd

return new SimpleDateFormat("yyyy-MM-dd").format(date);

}

}

页面显示代码如下

<body>

<s:form action="datesAction" />

<h2>自定义类型转换器</h2><br/>

请输入日期:<s:textfield name="currentDate" />

<s:submit value="提交" />

</body

七:处理类型转换器错误

  1. 前提条件:如果在服务器端判断类型转换错误。则需要满足一下条件。

(1.)启动StrutsConversionErrorLnterceptor拦截器。该拦截器已经包含在defaultStack拦截器栈中,参看Struts-default.xml文件,如果拓展此包启动时自动加载。

(2.)实现ValidationAware接口,ActionSupport实现了该接口。

(3.)配置input结果映射。出现类型转换错误将在所配置页面显示错误的信息,如果没有配置将出现错误的提示,提示没有指定的input页面。

(4.)在页面使用Struts 2表单标签或使用<s:fielderror>标签输出转换错误。Struts 2表单标签内嵌了输出错误的信息功能。

2.修改所有类型的转换错误信息。

可修改默认文本信息:

<constant  name=”struts.custom.il8n.resources” value=”message”>

然后在src目录下创建资源文件message.properties并添加文本如下:

Xwork.default.invalid.fieldvalue=字段”{0}”的值无效

3.制定特定字段类型转换错误信息。

Invalid.fieldvalue.timeDate=日期转换错误

八:OGNL表达式

  1. 表达式语音

(1.)访问Bean属性:代码如下

<s:form   action=”Register”>

<s:textfield  name=”user.address.streetName” label=”请输入街道名称.”  />

<s:submit  />

</s:form>

(2.)访问集合对象

public class ListAction extends ActionSupport{

private List hobbies;

private List<Integer> numbers;

private List<User> users;

public List getHobbies() {

return hobbies;

}

public void setHobbies(List hobbies) {

this.hobbies = hobbies;

}

public List<Integer> getNumbers() {

return numbers;

}

public void setNumbers(List<Integer> numbers) {

this.numbers = numbers;

}

public List<User> getUsers() {

return users;

}

public void setUsers(List<User> users) {

this.users = users;

}

public String execute1(){

for (int i = 0; i < hobbies.size(); i++) {

System.out.println("数组第:"+i+"元素,为"+hobbies.get(i));

}

System.out.println();

for (int i = 0; i < numbers.size(); i++) {

System.out.println("第"+i+"个元素,为"+numbers.get(i));

}

System.out.println();

for (int i = 0; i < numbers.size(); i++) {

System.out.println("第"+i+"个元素,为"+users.get(i).getName());

}

return SUCCESS;

}

}

页面代码如下:

<body>

!!!!!!迭代数组输出:

<h1>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!</h1>

<br />

<s:iterator value="likes">

<s:property />

<br />

</s:iterator>

<h1>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!</h1>

!!!!!!迭代集合(元素类型为Double):

<br />

<s:iterator value="numbers">

<s:property />

<br />

</s:iterator>

<h1>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!</h1>

!!!!!!迭代集合(元素类型为User):

<br />

<s:iterator value="users">

!!!!!! 用户名:<s:property value="name" />

<br />

!!!!!!年龄:<s:property value="age" />

<br />

!!!!!!国家:<s:property

value="address.country" />

<br />

!!!!!!城市:<s:property value="address.city" />

<br />

<h1>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!</h1>

</s:iterator>

<s:debug></s:debug>

</body>

(3.)对于集合对象的访问,在开发过程中往往还有一些几种情况

访问列表或者数组的某一个元素,可以使用属性[index]的方式。如userList[1].name

访问Map的某一个元素。可以使用属性名[key]如userMap[‘userA’].name

通过size或者length来访问集合的长度。

九:访问ActionContext中的数据

OGNL简介的更多相关文章

  1. 3:2 OGNL 简介

    OGNL : (对象图导航语言) 从一个对象到另一个对象 OGNL来源于Xwork: OGNL的作用: OGNL在数据进出值栈的时候进行类型转换

  2. OGNL和ValueStack

    OGNL简介 OGNL的全称是Object Graph Navigation Language,即对象导航图语言.它是一个开源项目,工作在视图层,其通过简单一致的表达式语言来读取合适者Java对象的属 ...

  3. 十七、OGNL表达式

    十七.OGNL OGNL简介: OGNL是对象导航图语言.它是一个独立的项目.早期的webwork框架用到了OGNL作为自己的表达式语言, 所以struts2也是用OGNL作为表达式语言,当然也可以使 ...

  4. Java实战之01Struts2-04拦截器、上传下载、OGNL表达式

    十二.Struts2中的拦截器 1.拦截器的重要性 Struts2中的很多功能都是由拦截器完成的.比如:servletConfig,staticParam,params,modelDriven等等. ...

  5. Struts 2 OGNL

    1.什么是OGNL? 2.Struts 2 OGNL 表达式      ======================  华丽丽的分割线  ======================  1.什么是OG ...

  6. JavaWeb框架SSH_Struts2_(四)----->表达式语言OGNL

    1. 表达式语言OGNL OGNL简介 OGNL基本语法 常量 操作符 OGNL表达式 OGNL基础 OGNL上下文 OGNL值栈 OGNL的访问 2. 具体内容 2.1 OGNL简介 OGNL(Ob ...

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

    OGNL简介: (1)OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目.  struts2框架默认就支持Ognl表达式语言(所以 ...

  8. JavaWeb框架_Struts2_(四)----->表达式语言OGNL

      2. 表达式语言OGNL 2.1 OGNL简介 OGNL(Object-Graph Navigation Language)对象图导航语言的缩写,OGNL是一种表达式语言(Expression L ...

  9. Struts2 OGNL表达式、ValueStack

    OGNL简介 OGNL,即Object-Graph Navigation Language,对象视图导航语言,是一种数据访问语言,比EL表达式更加强大: EL只能从11个内置对象中取值,且只能获取属性 ...

随机推荐

  1. 一个有意思的Python小程序(全国省会名称随机出题)

    本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 最近比较迷Python,仿照<Python编程快速上手>8.5写了一个随机出卷的小 ...

  2. 汇总一些知名的 JavaScript 开发开源项目

    汇总一些知名的 JavaScript 开发开源项目   转自:CTOLib , www.ctolib.com/topics-107352.html ggraph - 图形可视化的凌乱数据 这是一个建立 ...

  3. 数据分析与展示——NumPy库入门

    这是我学习北京理工大学嵩天老师的<Python数据分析与展示>课程的笔记.嵩老师的课程重点突出.层次分明,在这里特别感谢嵩老师的精彩讲解. NumPy库入门 数据的维度 维度是一组数据的组 ...

  4. angular指令之complie和link不得不说的故事

    angular指令比较晦涩难懂的就是complie和link字段了,什么时候该用complie?什么时候该用link?总是很难分别清楚.当理解了指令的真正编译原理的时候,就会发现这相当的简单. ng怎 ...

  5. [Scikit-learn] 4.4 Dimensionality reduction - PCA

    2.5. Decomposing signals in components (matrix factorization problems) 2.5.1. Principal component an ...

  6. Visual paradigm软件介绍

    Visual paradigm软件介绍 说起Visual Paradigm你可能并不陌生,因为此前有一款功能强大的UML软件叫Visual Paradigm for UML,在这款软件在v11.1的时 ...

  7. linux 安装 Elasticsearch5.6.x 详细步骤以及问题解决方案

    在网上有很多那种ES步骤和问题的解决 方案的,不过没有一个详细的整合,和问题的梳理:我就想着闲暇之余,来记录一下自己安装的过程以及碰到的问题和心得:有什么不对的和问题希望及时拍砖. 第一步:环境 li ...

  8. mkdir--命令

    mkdir命令 mkdir:make directory(ies)的缩写,用来创建目录 1.语法 mkdir [OPTION]... DIRECTORY 注释:option是选择,可选,directo ...

  9. python的学习之路day1

    软件:python3.pycharm开发工具 python的开始:print("hello world") 注意:python3需要加上() 1.变量是什么:在程序运行过程中它的值 ...

  10. js函数整合队列顺序执行插件

    前言 在日常开发中,也许我们会遇到这样的一个问题.我们利用[发布订阅模式](如果不了解的可以直接访问此链接www.cnblogs.com/xiaoxiaokun- )去执行[发布]事件时,遇到函数内部 ...