Struts2 关于OGNL的%#$的应用

一直没仔细的学习下OGNL,对其中的%#$的应用也一直很模糊,在这里进行记录一下,以备查阅:

转自:http://www.blogjava.net/max/archive/2007/04/28/114417.html

 

本人是一个EL(Expression Language,以下译为表达式语言)的支持者。因为我对<% %>写法极为反感,忘记了在那本书上看到的一句话——“使用标志(Tag)的一个目的就是避免在JSP页面中出现过多的<%%>的语句,使页面与后台代码分离。”

表达式语言主要有以下几大好处:

  1. 避免(MyType) request.getAttribute()和myBean.getMyProperty()之类的语句,使页面更简洁;
  2. 支持运算符(如+-*/),比普通的标志具有更高的自由度和更强的功能;
  3. 简单明了地表达代码逻辑,使用代码更可读与便于维护。

Struts 2中的表达式语言

Struts 2支持以下几种表达式语言:

  1. OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言;
  2. JSTL(JSP Standard Tag Library),JSP 2.0集成的标准的表达式语言;
  3. Groovy,基于Java平台的动态语言,它具有时下比较流行的动态语言(如Python、Ruby和Smarttalk等)的一些起特性;
  4. Velocity,严格来说不是表达式语言,它是一种基于Java的模板匹配引擎,具说其性能要比JSP好。

Struts 2默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:

  1. 支持对象方法调用,如xxx.doSomeSpecial();
  2. 支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 |  值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;
  3. 支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(),这个表达式会返回80;
  4. 访问OGNL上下文(OGNL context)和ActionContext;
  5. 操作集合对象。

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

“#”主要有三种用途:

  1. 访问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属性,直到找到为止
  2. 用于过滤和投影(projecting)集合,如books.{?#this.price<100};
  3. 构造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

“$”有两个主要的用途

  1. 用于在国际化资源文件中,引用OGNL表达式,例子请参考《在Struts 2.0中国际化(i18n)您的应用程序》
  2. 在Struts 2配置文件中,引用OGNL表达式,如
    < action name ="AddPhoto" class ="addPhoto" >
               
    < interceptor-ref name ="fileUploadStack" />            
               
    < result type ="redirect" > ListPhotos.action?albumId=${albumId} </ result >
           
    </ action >
    清单8 演示$用途的代码片段

总结

OGNL是一种功能很大的表达式语言,熟悉它可以使我们的开发变得更快捷。

YOLOv11官方代码库与预训练模型下载:介绍Ultralytics官方GitHub及模型权重(yolov11n.pt, yolov11s.pt等) 本文介绍了Ultralytics官方GitHub仓库和YOLOv11预训练模型。Ultralytics仓库是YOLO系列算法的官方实现,包含YOLOv11最新代码、预训练模型、文档和工具。仓库采用清晰的代码结构和活跃的更新策略,支持全流程开发。YOLOv11提供了5种不同规模的模型变体(YOLOv11n/s/m/l/x),在精度、速度和模型大小间权衡,适用于从移动设备到高精度检测等不同场景。各模型在COCO数据集上预训练,可直接使用或微调,满足多样化应用需求。 阅读详情

相关推荐

SVA学习笔记(1)——property基本语法及巧用define与property

巧用define与property,让代码更加灵活

craftsman2018ship的博客 1573

Struts 2中的OGNL

本人是一个EL(Expression Language,以下译为表达式语言)的支持者。因为我对写法极为反感,忘记了在那本书上看到的一句话——“使用标志(Tag)的一个目的就是避免在JSP页面中出现过多的的语句,使页面与后台代码分离。”表达式语言主要有以下几大好处: 避免(MyType) request.getAttribute()和myBean.getMyProperty()之类

boy_wh520的专栏 2127

AD9361快速锁定实战:Profile寄存器配置与频率调谐算法解析

本文深入解析了AD9361射频收发器的快速锁定(Fast Lock)功能,重点阐述了其核心机制——Profile寄存器配置。通过剖析16字节Profile结构,详细讲解了频率调谐算法,包括LO_DIV、LO_INT、LO_FRAC等关键参数的计算,以及如何通过查表获取优化的环路滤波器参数。文章提供了完整的Python算法示例和FPGA实现要点,旨在帮助工程师实现毫秒级甚至微秒级的频率切换,满足跳频通信等高性能应用需求。

weixin_29196315的博客 228

struts2中的OGNL表达式

OGNL:Object-Graph Navigation Language,即对象图导航语言,它在struts2中很强大,但是离开了struts2基本上没什么用,其他框架很少支持这个语言。它可以访问对象的任意属性和方法,struts2会解析表达式的内容,有与表达式相关的数据则会显示,否则什么都不显示&lt;s:property value="justtest"/&gt;&lt;br&gt;    ...

dimples_qian的博客 213

SAP成本核算-事中控制(成本对象控制/成本归集与结算)

本文详细介绍了SAP系统中工单成本归集与结算的全流程管理。主要内容包括:1)工单成本三阶段归集(投料、报工、入库)的具体操作与计算方法;2)工单实际成本结算七步骤:从实际费用归集、成本分割、作业价格计算到差异结算的全过程;3)关键注意事项如测试运行验证、价格单位确认、无在制品处理等。通过标准价计算、实际作业重估等机制,系统实现了生产成本从计划到实际的精确核算,最终生成财务所需的差异结算凭证。所有操作均提供单工单和批量处理两种方式,满足不同业务场景需求。

小九啥也不会 1363

STM32实战指南:TFTLCD液晶屏驱动与ILI9341应用解析

本文详细解析了STM32驱动TFTLCD液晶屏的实战技巧,重点介绍了ILI9341控制器的硬件连接、寄存器操作及性能优化方法。通过8080并行接口时序分析、GRAM操作优化和DMA传输应用,帮助开发者高效实现液晶屏驱动,适用于工业控制、智能家居等场景。

weixin_26873711的博客 232

OGNL 表达式

mybatis的OGNL表达式

m0_49261516的博客 9544

innovus:Clock Gating Check设置与报告

看图后发现,在设置clock gating check之前报告也会有clock gating check的值,这个就是因为timing library中会像reg一样定 library setup time值,如下图。我们常用set_clock_gating_check -setup去过约束Place阶段reg2cgate的时序,以防CTS后由于tree不平导致的时序违例。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 1009

mybatis的ognl表达式

OGNL(Object-Graph Navigation Language的简称),对象图导航语言,通过表达式来实现:许多常用框架都集成了ognl,如mybatis、struts、spring、arthas等。这里仅以java环境下的代码进行演示。

pscool的博客 2339

YOLOv8 模型进化全解析:百种创新模块集成方法与实战部署指南(附资料链接)

动态网络 | DeformableConv/DynamicHead| +2.8% || 轻量化卷积 | GhostConv/MobileConv | +1.2% || 多尺度融合 | AFPN/ASFF | +3.5% || 注意力机制 | CA/EMA/SimAM | +1.8-4.2% |

FJN110的博客 110

40、基于指令的GPU编程:OpenACC与OpenMP的深入解析

本文深入解析了两种基于指令的GPU编程模型——OpenACC和OpenMP。从编程复杂度、数据处理方式和性能表现等多个方面对两者进行了对比分析,并结合实际应用场景提供了选择建议。通过详细的代码示例和性能测试结果,帮助开发者更好地理解和应用这两种编程模型,以充分发挥GPU的并行计算能力。

q5r6s7的博客 134

struts2的ognl标签详解

OGNL表达式struts2标签“%,#,$” 一、什么是OGNL,有什么特点?     OGNL(Object-Graph Navigation Language),大概可以理解为:对象图形化导航语言。是一种可以方便地操作对象属性的开源表达式语言。OGNL有如下特点:      1、支持对象方法调用,形式如:objName.methodName();   2、支持类静态的方法调用和值访问,

u012505903的专栏 326

置顶必读(3) |《滚雪球学SpringBoot》· 高质量专栏介绍,你值得拥有!

《滚雪球学SpringBoot》 并不是普通的技术讲解合集,它是专为开发者精心设计的系统化学习路径。通过不断“滚动学习”,我们将带领你从基础入门到高阶应用,从理解每一行代码到设计和优化大规模分布式系统,最终帮助你成长为一位精通 spring架构 的工程师。

**My Coding Family** 15万+

struts2中使用ognl表达式时各种符号的使用规则$,#,%

struts2中使用ognl表达式时各种符号的使用规则$,#,% OGNL表达式struts2标签“%,#,$” 一、什么是OGNL,有什么特点? OGNL(Object-GraphNavigationLanguage),大概可以理解为:对象图形化导航语言。是一种可以方便地操作对象属性的开源表达式语言。OGNL有如下特...

weixin_30682127的博客 122

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

OGNL表达式struts2标签“%,#,$”

OGNL表达式struts2标签“%,#,$” 一、什么是OGNL,有什么特点?     OGNL(Object-Graph Navigation Language),大概可以理解为:对象图形化导航语言。是一种可以方便地操作对象属性的开源表达式语言。OGNL有如下特点:      1、支持对象方法调用,形式如:objName.methodName();     2、支持类静态的方法调用和值访

a363722188的专栏 482

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

OGNL表达式使用

原文地址:http://www.blogjava.net/parable-myth/archive/2010/10/28/336353.html OGNL表达式struts2标签“%,#,$” 一、什么是OGNL,有什么特点?     OGNL(Object-Graph Navigation Language),大概可以理解为:对象图形化导航语言。是一种可以方便地操作对象属

彻底拆分,一切可控! 548

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

STRUTS2中的OGNL

[类全名(包括包路经)]@[方法名|值名]例如:访问OGNL上下文(OGNLcontext)和ActionContext操作集合对象类图ValueStackValueStack是一个接口,在struts2中使用OGNL表达式实际上是使用实现了ValueStack接口的类OgnlValueStack,这个类是OgnlValueStack的基础。ValueStack贯穿整个action的生命周期。每一个action实例都拥有一个ValueStack对象。

2501_90251017的博客 966

OGNL在Struts2中的应用

在上篇讲述OGNL基础知识的博客中,我们可以得到如下知识点: 1、OGNL表达式需要放置到OgnlContext中才能得到正确地解析、解释和执行; 2、OgnlContext类实现了Map接口,所以可以使用put方法向里面放置元素且每个OgnlContext有且最多只能有一个根对象; 3、Ognl表达式中访问根对象的属性时,无需"#",普通对象则需要; 上面知识了解后,咱们再来聊聊Stru

yu102655的专栏 3110

Struts2入门第七讲——OGNL

OGNL的概述什么是OGNL据度娘所说: OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化功能。它使用相同的表达式去存取对象的属性。 OGNL的全称是对象图导航语言(Object-Graph Navigation Languag

李阿昀的博客 3337

struts2中的Ognl

struts2中的Ognl

博客 2772
上一篇: 如何提升Eclipse性能
下一篇: Struts2 OGNL遍历
javaRwx
博客等级 码龄20年 0粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值