OGNL简介

OGNL简介

大家好,又见面了,我是全栈君。

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中的数据

 

转载于:https://www.cnblogs.com/dkz1/p/8024675.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107843.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 差分数组C++「建议收藏」

    差分数组C++「建议收藏」差分数组在数组某一段数值同乘以一个值,或者求某数组的前n项和非常方便inta[]={0,1,2,3,4,5};b[i]=a[i]-a[i-1];(1<i≤n,b[1]=a[1],a[0]=b[0]=0)b[]={0,1,1,1,1,1}则称b[]是a的差分数组,它具有的性质是a[i]=b[i]+b[i-1]+…+b[1];如果要在数…

  • Iocomp 5.12 SP6 ActiveX Crack

    Iocomp 5.12 SP6 ActiveX Crack不需要安装,免去大家下载,Q578867473安装需要注册账号的麻烦的IocompActiveX/VCL标准包是由29个控件组成的套件,Q578867473用于使用ActiveX或VCL开发环境创建专业的仪表应用程序。这些控件可用于科学,工程,医学,石油和天然气,半导体,工厂自动化,航空航天,军事,机器人技术,电信,楼宇和家庭自动化,HMI,SCADA以及数百种其他类型的应用程序。所有Iocomp控件均启用OPC。如果您的项目需要OPC连接,则可以将任何属性连接到OPC项/标签。所有连接都可

  • PL/SQL连接oracle数据库

    PL/SQL连接oracle数据库

  • 中标麒麟/NeoKylin U盘安装系统「建议收藏」

    中标麒麟/NeoKylin U盘安装系统「建议收藏」这里以NeoKylin6为例,其他版本与此相类似大同小异。但是下载指定版本的镜像时要注意配合该版本的软件包是否充足,不然就会遇到安装好系统很多软件无法安装或更新的情况。1.官方下载地址:http://download.cs2c.com.cn/neokylin/desktop/releases/2.第二步,在上个地址中找你想要下载的版本,注意前面说的先检查下资源,以我想下载的版本6.0为…

  • 什么是多线程,什么是高并发?[通俗易懂]

    什么是多线程,什么是高并发?[通俗易懂]高并发和多线程”总是被一起提起,给人感觉两者好像相等,实则 高并发≠多线程多线程是完成任务的一种方法,高并发是系统运行的一种状态,通过多线程有助于系统承受高并发状态的实现。高并发是一

  • vmware 安装 win10[通俗易懂]

    vmware 安装 win10[通俗易懂]1.下载安装vm软件,地址:VM下载2.下载win10iso镜像文件(1)下载win10安装工具:win10安装工具下载(2)下载完成后,选择给其他电脑安装ios文件即可得到win10的iso镜像文件(考验网速的时刻到了)。ps:试过各种百度出来的镜像文件,发现没有能用的,还是乖乖通过官方方式下载吧。3.安装win10ios镜像文件参…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号