Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 253|回复: 0

[struts学习]Struts 2中的OGNL

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-11 06:15:52 | 显示全部楼层 |阅读模式
    本人是一个EL(Expression Language,以下译为表达式语言)的支持者。因为我对<% %>写法极为反感,忘记了在那本书上看到的一句话――“使用标志(Tag)的一个目的就是避免在JSP页面中出现过多的<%%>的语句,使页面与后台代码分离。” 表达式语言主要有以下几大好处:
       
        避免(MyType) request.getAttribute()和myBean.getMyProperty()之类的语句,使页面更简洁;
        支持运算符(如+-*/),比普通的标志具有更高的自由度和更强的功能;
        简单明了地表达代码逻辑,使用代码更可读与便于维护。  
        Struts 2中的表达式语言 Struts 2支持以下几种表达式语言:
       
        OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言;
        JSTL(JSP Standard Tag Library),JSP 2.0集成的标准的表达式语言;
        Groovy,基于java平台的动态语言,它具有时下比较流行的动态语言(如python、Ruby和Smarttalk等)的一些起特性;
        Velocity,严格来说不是表达式语言,它是一种基于Java的模板匹配引擎,具说其性能要比JSP好。  
        Struts 2默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:
       
        支持对象方法调用,如xxx.doSomeSpecial();
        支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 |  值名],例如:@java.lang.String@format("foo %s", "bar")或@tutorial.MyConstant@APP_NAME;
        支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(),这个表达式会返回80;
        访问OGNL上下文(OGNL context)和ActionContext;
        操作集合对象。  
        OGNL的用法 OGNL是通常要结合Struts 2的标志一起使用,如<s:property value="xx" />等。大家经常遇到的问题是#、%和$这三个符号的使用。下面我想通过例子讲述这个问题: 首先新建名为Struts2_OGNL的Web工程,配置开发环境。之前很多朋友在使用Struts 2的过程中都遇到乱码问题。当然乱码问题由来已久,而且涉及多方面的知识,所以并非三言两语可以说明白,而且互联网上也已经有很多这方便的文章,大家可以Google一下。不过,如果你在开发的过程,多注意一下,避免乱码问题也不难。乱码多数是由于编码与解码所使用的方式不同造成的,所以我建议大家将编码方式都设为“utf-8”,如<%@  page language="java" contentType="text/HTML; charset=utf-8" pageEncoding="utf-8" %>。另外,在配置web.xml时使用ActionContextCleanUp过滤器(Filter),如下面代码所示:
       
        <?
        xml version="1.0" encoding="UTF-8"
        ?>
       

        <
        web-app
        id
        ="WebApp_9"
         version
        ="2.4"
       
         xmlns
        ="http://java.sun.com/xml/ns/j2ee"
       
         xmlns:xsi
        ="http://www.w3.org/2001/XMLSchema-instance"
       
         xsi:schemaLocation
        ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
        >
       

         
        <
        display-name
        >
        Struts 2 OGNL
        </
        display-name
        >
       
         
         
        <
        filter
        >
       
             
        <
        filter-name
        >
        struts-cleanup
        </
        filter-name
        >
       
             
        <
        filter-class
        >
       
                 org.apache.struts2.dispatcher.ActionContextCleanUp
             
        </
        filter-class
        >
       
         
        </
        filter
        >
       
         
         
        <
        filter-mapping
        >
       
             
        <
        filter-name
        >
        struts-cleanup
        </
        filter-name
        >
       
             
        <
        url-pattern
        >
        /*
        </
        url-pattern
        >
       
         
        </
        filter-mapping
        >
       
         
         
        <
        filter
        >
       
             
        <
        filter-name
        >
        struts2
        </
        filter-name
        >
       
             
        <
        filter-class
        >
       
                 org.apache.struts2.dispatcher.FilterDispatcher
             
        </
        filter-class
        >
       
         
        </
        filter
        >
       

         
        <
        filter-mapping
        >
       
             
        <
        filter-name
        >
        struts2
        </
        filter-name
        >
       
             
        <
        url-pattern
        >
        /*
        </
        url-pattern
        >
       
         
        </
        filter-mapping
        >
       

         
        <
        welcome-file-list
        >
       
             
        <
        welcome-file
        >
        index.html
        </
        welcome-file
        >
       
         
        </
        welcome-file-list
        >
       


        </
        web-app
        >
        清单1 WebContent/WEB-INF/web.xml “#”主要有三种用途:
       
        访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性:


          
          
            
             名称
            作用
            例子
            
            
            parameters
            包含当前HTTP请求参数的Map
            #parameters.id[0]作用相当于request.getParameter("id")
            
            
            request
            包含当前HttpServletRequest的属性(attribute)的Map
            #request.userName相当于request.getAttribute("userName")
            
            
            session
            包含当前HttpSession的属性(attribute)的Map
            #session.userName相当于session.getAttribute("userName")
            
            
            application
            包含当前应用的ServletContext的属性(attribute)的Map
            #application.userName相当于application.getAttribute("userName")
            
            
            attr
            用于按request > session > application顺序访问其属性(attribute)
            #attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止
            
          
          

        用于过滤和投影(projecting)集合,如books.{?#this.price<100};
        构造Map,如#{"foo1":"bar1", "foo2":"bar2"}。  
        下面让我们它们的具体写法,首先是Action类代码:
       
       
        package
         tutorial.action;


        import
         java.util.LinkedList;

        import
         java.util.List;

        import
         java.util.Map;


        import
         javax.servlet.ServletContext;

        import
         javax.servlet.http.HttpServletRequest;


        import
         org.apache.struts2.interceptor.ServletRequestAware;

        import
         org.apache.struts2.interceptor.SessionAware;

        import
         org.apache.struts2.util.ServletContextAware;


        import
         tutorial.model.Book;


        import
         com.opensymphony.xwork2.ActionSupport;


        public
         
        class
         OgnlAction
        extends
         ActionSupport
        implements
         ServletRequestAware, SessionAware, ServletContextAware  
       
        {
        private static final long serialVersionUID = 1L;
       
        private HttpServletRequest request;
        private Map<String, String> session;
        private ServletContext application;
        private List<Book> books;
                
        public void setServletRequest(HttpServletRequest request) {
            this.request = request;   
        }

        @SuppressWarnings("unchecked")
        public void setSession(Map session) {
            this.session = session;        
        }

        public void setServletContext(ServletContext application) {
            this.application = application;
        }
       
        public List<Book> getBooks() {
            return books;
        }

        @Override
        public String execute() {
            request.setAttribute("userName", "Max From request");
            session.put("userName", "Max From session");
            application.setAttribute("userName", "Max From application");
            
            books = new LinkedList<Book>();
            books.add(new Book("978-0735619678", "Code Complete, Second Edition", 32.99));
            books.add(new Book("978-0596007867", "The Art of Project Management", 35.96));
            books.add(new Book("978-0201633610", "Design Patterns: Elements of Reusable Object-Oriented Software", 43.19));
            books.add(new Book("978-0596527341", "Information Architecture for the World Wide Web: Designing Large-Scale Web Sites", 25.19));
            books.add(new Book("978-0735605350", "Software Estimation: Demystifying the Black Art", 25.19));
            
            return SUCCESS;
        }
    }
        清单2 src/tutorial/action/OgnlAction.java
    以上代码分别在request、session和application的范围内添加“userName”属性,然后再在JSP页面使用OGNL将其取回。我还创建了Book对象的列表用于演示“用于过滤和投影(projecting)集合”的功能,至于Book的代码大家可以在我前一文章《在Struts 2中实现CRUD》看到。 下面是Ognl.jsp的代码,内容如下:
       
        <%
        @ page language
        =
        "
        java
        "
         contentType
        =
        "
        text/html; charset=utf-8
        "
         pageEncoding
        =
        "
        utf-8
        "
         
        %>
       

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


        <!
        DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
        >
       

        <
        html
        xmlns
        ="http://www.w3.org/1999/xhtml"
        >
       

        <
        head
        >
       
         
        <
        title
        >
        Struts OGNL Demo
        </
        title
        >
       

        </
        head
        >
       

        <
        body
        >
            
         
        <
        h3
        >
        访问OGNL上下文和Action上下文
        </
        h3
        >
       
         
        <
        p
        >
        parameters:
        <
        s:property
        value
        ="#parameters.userName"
         
        /></
        p
        >
       
         
        <
        p
        >
        request.userName:
        <
        s:property
        value
        ="#request.userName"
         
        /></
        p
        >
       
         
        <
        p
        >
        session.userName:
        <
        s:property
        value
        ="#session.userName"
         
        /></
        p
        >
       
         
        <
        p
        >
        application.userName:
        <
        s:property
        value
        ="#application.userName"
         
        /></
        p
        >
       
         
        <
        p
        >
        attr.userName:
        <
        s:property
        value
        ="#attr.userName"
         
        /></
        p
        >
       
         
        <
        hr
        />
       
         
        <
        h3
        >
        用于过滤和投影(projecting)集合
        </
        h3
        >
       
         
        <
        p
        >
        Books more than $35
        </
        p
        >
       
         
        <
        ul
        >
       
             
        <
        s:iterator
        value
        ="books.{?#this.price > 35}"
        >
       
                
        <
        li
        ><
        s:property
        value
        ="title"
         
        />
         - $
        <
        s:property
        value
        ="price"
         
        /></
        li
        >
       
             
        </
        s:iterator
        >
       
         
        </
        ul
        >
       
         
        <
        p
        >
        The price of "Code Complete, Second Edition" is:
        <
        s:property
        value
        ="books.{?#this.title=="Code Complete, Second Edition"}.{price}[0]"
        /></
        p
        >
       
         
        <
        hr
        />
       
         
        <
        h3
        >
        构造Map
        </
        h3
        >
       
         
        <
        s:set
        name
        ="foobar"
         value
        ="#{"foo1":"bar1", "foo2":"bar2"}"
         
        />
       
         
        <
        p
        >
        The value of key "foo1" is
        <
        s:property
        value
        ="#foobar["foo1"]"
         
        /></
        p
        >
       

        </
        body
        >
       

        </
        html
        >
        清单3 WebContent/Ognl.jsp 以上代码值得注意的是“<s:property value="books.{?#this.title=="Code Complete, Second Edition"}.{price}[0]"/>”,因为“books.{?#this.title=="Code Complete, Second Edition"}.{price}”返回的值是集合类型,所以要用“[索引]”来访问其值。 最后是Struts 2的配置文件struts.xml,内容如下:
       
        <?
        xml version="1.0" encoding="UTF-8"
        ?>
       


        <!
        DOCTYPE struts PUBLIC
         "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
         "http://struts.apache.org/dtds/struts-2.0.dtd"
        >
       


        <
        struts
        >
       
         
        <
        constant
        name
        ="struts.devMode"
         value
        ="true"
         
        />
       
         
        <
        package
        name
        ="Struts2_OGNL_DEMO"
         extends
        ="struts-default"
        >
       
             
        <
        action
        name
        ="Ognl"
         class
        ="tutorial.action.OgnlAction"
        >
       
                
        <
        result
        >
        /Ognl.jsp
        </
        result
        >
       
             
        </
        action
        >
                
         
        </
        package
        >
       

        </
        struts
        >
        清单4 src/struts.xml
    发布运行应用程序,结果如下所示:
    清单5 示例运行结果1 “%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。例如在Ognl.jsp中加入以下代码:
       
        <
        hr
        />
       
         
        <
        h3
        >
        %的用途
        </
        h3
        >
       
         
        <
        p
        ><
        s:url
        value
        ="#foobar["foo1"]"
         
        /></
        p
        >
       
         
        <
        p
        ><
        s:url
        value
        ="%{#foobar["foo1"]}"
         
        /></
        p
        >
        清单6 演示%用途的代码片段 刷新页面,结果如下所示: 清单7 示例运行结果2 “$”有两个主要的用途
       
        用于在国际化资源文件中,引用OGNL表达式,例子请参考《在Struts 2.0中国际化(i18n)您的应用程序


        在Struts 2配置文件中,引用OGNL表达式,如



         
          <
          action
          name
          ="AddPhoto"
           class
          ="addPhoto"
          >
          
                
          <
          interceptor-ref
          name
          ="fileUploadStack"
          
          />
                      
                
          <
          result
          type
          ="redirect"
          >
          ListPhotos.action?albumId=
          </
          result
          >
          
             
          </
          action
          >
          清单8 演示$用途的代码片段
        总结 OGNL是一种功能很大的表达式语言,熟悉它可以使我们的开发变得更快捷。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-26 07:36 , Processed in 0.304753 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表