I. Introduction
The role of OGNL and tag library, to put it rudely, is to reduce the appearance of java code in JSP pages, which is conducive to maintenance.
1.1 、 OGNL
1.1.1. What is OGNL?
OGNL (Object-Graph Navigation Language): Object Graph Navigation Language, is a powerful expression language. Through simple syntax, you can arbitrarily access the properties of objects or call methods of objects, and can traverse the structure diagram of the entire object , to implement the type conversion function of object properties.
1.1.2 Basic knowledge of OGNL
1. OGNL expressions are evaluated around the OGNL context
The OGNL context is actually a Map object, represented by the ognl.OgnlContext class. It can store many JavaBean objects.
2.Struts2 tag library uses OGNL expressions to access object data in ActionContext. For example: <s:propertyvalue="xxx"/>.
3.Struts2 sets the ActionContext as the OGNL context, and places the value stack into the ActionContext as the root object of OGNL.
4. ValueStack (ValueStack):
Objects can be placed, deleted, and queried in the value stack. Accessing objects on the value stack does not require "#".
Struts2 always places the current Action instance at the top of the stack. Therefore, you can also omit the "#" when referring to the attribute in the Action in OGNL.
5. The data put in by calling put(key, value) of ActionContext needs to be accessed using #.
OGNL context storage graph
1.1.3. There are three important symbols in OGNL: #, %, $
The purpose of the "#" symbol:
1. To access non-root objects, such as #session.msg expressions, since the value stack in Struts 2 is regarded as a root object, you need to add # prefix when accessing other non-root objects. In fact, # is equivalent to ActionContext.getContext(); #session.msg expressions are equivalent to ActionContext.getContext().getSession().getAttribute("msg") .
2. For filtering and projecting collections, such as persons.{?#this.age>25}.{age}, persons.{?#this.name=='pla1'}.{age}[0] . (persons: represents the value stored in the contained object. The question mark? is to take out all the elements that satisfy the condition. )
3. Construct Map and List
The purpose of the "%" symbol:
The purpose of the "%" symbol is to tell the execution environment that %{} is an OGNL expression when the attribute value of the tag is interpreted as a string type. (Wait for an example below)
The purpose of the "$" symbol:
1. In the internationalized resource file, refer to the OGNL expression, such as the code in the internationalized resource file: reg.agerange=Internationalized resource information: age must be between ${min} and ${max}.
2. Refer to the OGNL expression in struts.xml, such as:
The following is an example to illustrate:
Create a new jsp page:
<%@page import="java.util.LinkedList"%> <%@page import="java.util.List"%> <%@page import="com.Ogml.Persons"%> <%@page import="org.apache.struts2.ServletActionContext"%> <%@page import="com.opensymphony.xwork2.ActionContext"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!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>学习OGNL</title> </head> <body> <% ActionContext ctx = ActionContext.getContext(); ctx.getApplication().put("msg", "application消息"); ctx.getSession().put("msg","session消息"); ctx.getParameters().put("msg", "parameters消息"); HttpServletRequest re = ServletActionContext.getRequest(); re.setAttribute("msg", "request消息"); %> <!-- 使用OGNL访问属性值 --> <!--OGNL中的#号可以取出堆栈上下文中存放的对象 --> <p>parameters:<s:property value="#parameters.msg"/></p> <p>Application:<s:property value="#application.msg"/></p> <p>session:<s:property value="#session.msg"/></p> <p>request:<s:property value="#request.msg"/></p> <!-- 使用attr:表示它会自动从request-session-applicatioin中寻找,如果找到则返回 --> <p>attr:<s:property value="#attr.msg"/></p> <!--使用OGNL处理集合List,Map--> <p>使用List集合:<s:select name="color" list="{'red','yellow','green'}" /></p> <p>使用Map集合: <s:set var="colors" value="#{'color1':'yellow' }"/> <s:property value="#colors['color1']"/></p> <!-- 不使用%输出结果是:#colors['color1'] --> <p>不使用%:<s:url value="#colors['color1']"/></p> <!-- “%”符号的用途是在标签的属性值被理解为字符串类型时,告诉执行环境%{}里的是OGNL表达式。 --> <p>使用%:<s:url value="%{#colors['color1']}"/></p> <!-- 过滤和投影(projecting) --> <% Persons p1 = new Persons(); p1.setUname("lisi"); p1.setAge(36); application.setAttribute("p", p1); %> <!-- 问号?是把所有满足条件的元素都取出来。 --> <!-- {?#this.age>20}表示的是:获取当前对象的属性,这是一个表达式,如果是true的话,则后面查询的值会输出。false则不会 --> <p>使用?#:<s:property value="#application.p.{?#this.age>20}.{uname}"/></p> <!-- 输出的是[lisi],有中括号的表示这是一个列表 --> <!-- 上箭头^是开始的意思,即取符合条件的数据索引中第一条数据 --> <p>使用^#:<s:property value="#application.p.{^#this.age>20}.{age}[0]"/></p> <!-- 输出的是36,没有中括号,表示这个一个字符串 --> <!-- 前提必须在strtus.xml中添加 <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant> --> <!-- 使用@访问静态方法 --> <s:property value="@com.Ogml.Persons@sayhello()"/> <!-- 使用@访问静态属性 --> <s:property value="@com.Ogml.Persons@sex"/><br/> </body> </html>
例子中有使用到^、@符号:
^符号表示的是去符合条件的第一条数据
@符号表示调用类的静态方法或者属性
另外还有美元符号$是结束的意思,即取符合条件的数据索引中最后一条数据,如:
#application.p.{$#this.age>=60}.{uname}输出的是[zhangsan]。
注意:如果使用OGNL要调用静态方法(但是据说Struts2最新版本不允许使用静态方法了,好像说是安全问题。有兴趣可以自己试下)或者静态属性的时候,struts.xml一定要配置:
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>,该语句,不然无法调用。如下:
persons类代码如下:
仅作为笔记记录。
1.2、标签库
笔者对于标签库这些,真的不太感兴趣。但是没办法,还是的学着,发下牢骚。
1.2.1、标签库的好处
在Struts2中,它提供了大量的标签来生成页面效果,简单说来就是使用标签库中为我们提供的标签来达到我们想过的页面效果。而且标签库的使用非常简单,struts2把所有的标签都定义在URI为"/struts-tags"的命名空间下,我们只需要在页面中引入:<%@ taglib uri="/struts-tags" prefix="s"%>,就可以使用该标签库。
1.2.2、标签库的简单分类
UI标签:主要用于生产HTML元素的标签
非UI标签:主要用户数据访问,逻辑控制标签等
Ajax标签:用户Ajax支持的标签
对于UI标签,则可以分为两类:
1、表单标签:主要生成HTML页面的form元素以及普通标签元素
2、非表单标签:主要用于生成页面上的数据,tag页等标签
非UI标签,也可以分为两类:
1、流程控制标签:主要用于实现分支,循环等流程控制的标签
2、数据访问标签:主要包含输出valueStack中的值,完成国际化等功能的标签
这样就清晰多了。