1.OGNL表达式

  object graph navigation language:对象图导航语言

  存取对象属性;调用对象方法;字段类型转换等。

<input type="text" name="user.username" />

2.OGNL表达式的使用场景

2.1 在jsp中

s1.导入struts标签库:

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

s2. 只能在在struts标签库中使用OGNL表达式,不能再其他地方用

    对于property的value默认使用OGNL表达式。

  对于radio的list属性默认使用OGNL表达式

  纯字符串:

<s:property value="%{'OGNLExpression'}" />
<s:property value="'OGNLExpression'" />

  使用OGNL表达式:

<s:textfield value="%{name}" label="姓名" />

  调用对象方法:

<s:textfield value="%{'admin'.length()}" label="姓名" />
<s:textfield value="%{'admin'.split('m')}" label="姓名" />

  调用静态类的静态成员:

<s:property value="@java.lang.Math@PI" /><br />  静态成员
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />  开启允许调用OGNL静态方法【struts.xml中配置】
<s:property value="@java.lang.Math@random()" />  静态方法

  操作List对象:{'',''}  -->ArrayList-->['','']

<s:radio name="gender" list="{'male','female'}" label="性别"></s:radio>  list属性默认使用OGNL表达式

  操作Map对象:#{'':'' , '':''} -->Map -->{'':'', '':''}

<s:radio name="sex" list="#{'1':'男','2':'女'}" label="性别2"></s:radio>

3.OGNL表达式上下文:ContextMap

  contextMap是struts2封装好的一次请求可能出现的最大的数据容器。

  结构:是一个Map结构 {String:Object}

  里面存的数据:

  • application:ServletContext应用对象
  • session:HttpSession
  • valueStack:值栈    List类型
  • action:当前执行的动作类相关数据  【不是Map类型】
  • request:HttpServletRequest
  • parameters:请求参数
  • attr:四大域的属性数据

除了ValueStack和action不是Map类型的,其他的都是Map类型{String : Object}

4.ActionContext和ContextMap的关系

  ActionContext可以获取四大域对象,他是个工具类。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.opensymphony.xwork2; import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.util.ValueStack;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map; public class ActionContext implements Serializable {
static ThreadLocal<ActionContext> actionContext = new ThreadLocal();
public static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContext.name";
public static final String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
public static final String SESSION = "com.opensymphony.xwork2.ActionContext.session";
public static final String APPLICATION = "com.opensymphony.xwork2.ActionContext.application";
public static final String PARAMETERS = "com.opensymphony.xwork2.ActionContext.parameters";
public static final String LOCALE = "com.opensymphony.xwork2.ActionContext.locale";
public static final String TYPE_CONVERTER = "com.opensymphony.xwork2.ActionContext.typeConverter";
public static final String ACTION_INVOCATION = "com.opensymphony.xwork2.ActionContext.actionInvocation";
public static final String CONVERSION_ERRORS = "com.opensymphony.xwork2.ActionContext.conversionErrors";
public static final String CONTAINER = "com.opensymphony.xwork2.ActionContext.container";
private Map<String, Object> context; public ActionContext(Map<String, Object> context) {
this.context = context;
} public void setActionInvocation(ActionInvocation actionInvocation) {
this.put("com.opensymphony.xwork2.ActionContext.actionInvocation", actionInvocation);
} public ActionInvocation getActionInvocation() {
return (ActionInvocation)this.get("com.opensymphony.xwork2.ActionContext.actionInvocation");
} public void setApplication(Map<String, Object> application) {
this.put("com.opensymphony.xwork2.ActionContext.application", application);
} public Map<String, Object> getApplication() {
return (Map)this.get("com.opensymphony.xwork2.ActionContext.application");
} public static void setContext(ActionContext context) {
actionContext.set(context);
} public static ActionContext getContext() {
return (ActionContext)actionContext.get();
} public void setContextMap(Map<String, Object> contextMap) {
getContext().context = contextMap;
} public Map<String, Object> getContextMap() {
return this.context;
} public void setConversionErrors(Map<String, Object> conversionErrors) {
this.put("com.opensymphony.xwork2.ActionContext.conversionErrors", conversionErrors);
} public Map<String, Object> getConversionErrors() {
Map<String, Object> errors = (Map)this.get("com.opensymphony.xwork2.ActionContext.conversionErrors");
if (errors == null) {
errors = new HashMap();
this.setConversionErrors((Map)errors);
} return (Map)errors;
} public void setLocale(Locale locale) {
this.put("com.opensymphony.xwork2.ActionContext.locale", locale);
} public Locale getLocale() {
Locale locale = (Locale)this.get("com.opensymphony.xwork2.ActionContext.locale");
if (locale == null) {
locale = Locale.getDefault();
this.setLocale(locale);
} return locale;
} public void setName(String name) {
this.put("com.opensymphony.xwork2.ActionContext.name", name);
} public String getName() {
return (String)this.get("com.opensymphony.xwork2.ActionContext.name");
} public void setParameters(Map<String, Object> parameters) {
this.put("com.opensymphony.xwork2.ActionContext.parameters", parameters);
} public Map<String, Object> getParameters() {
return (Map)this.get("com.opensymphony.xwork2.ActionContext.parameters");
} public void setSession(Map<String, Object> session) {
this.put("com.opensymphony.xwork2.ActionContext.session", session);
} public Map<String, Object> getSession() {
return (Map)this.get("com.opensymphony.xwork2.ActionContext.session");
} public void setValueStack(ValueStack stack) {
this.put("com.opensymphony.xwork2.util.ValueStack.ValueStack", stack);
} public ValueStack getValueStack() {
return (ValueStack)this.get("com.opensymphony.xwork2.util.ValueStack.ValueStack");
} public void setContainer(Container cont) {
this.put("com.opensymphony.xwork2.ActionContext.container", cont);
} public Container getContainer() {
return (Container)this.get("com.opensymphony.xwork2.ActionContext.container");
} public <T> T getInstance(Class<T> type) {
Container cont = this.getContainer();
if (cont != null) {
return cont.getInstance(type);
} else {
throw new XWorkException("Cannot find an initialized container for this request.");
}
} public Object get(String key) {
return this.context.get(key);
} public void put(String key, Object value) {
this.context.put(key, value);
}
}

ActionContext

  ContextMap是一个Map类型的对象,key为application等,value为Map类型的数据,但是通过ContextMap.get(application)返回的是Object类型的对象。因此可以通过ActionContext工具类直接获取Map对象。

  域对象:

com.opensymphony.xwork2.dispatcher.HttpServletxxx

  ContextMap中的数据:

com.opensymphony.xwork2.ActionContext.application

  源码分析:ActionContext.java

   static ThreadLocal<ActionContext> actionContext = new ThreadLocal();
   private Map<String, Object> context;   //传说中的ContextMap
  public static ActionContext getContext() {
return (ActionContext)actionContext.get();
}

获取线程安全的ActionContext对象

  ServletActionContext.java

    public static HttpServletRequest getRequest() {
return (HttpServletRequest)ActionContext.getContext().get("com.opensymphony.xwork2.dispatcher.HttpServletRequest");
}

  通过ActionContext.getContext()静态方法可以获取一个线程安全的ActionContext对象,然后再调用里面的get方法:

  由此可知:域对象(ServletContext)、域对象数据(Map)都是存在context(Map<String, Object>)属性中的

  注意:ActionContext的声明周期为一次请求。

  ContextMap: {key: value}

application:Map

ActionContext.application:Map

servlet.ServletContext:ServletContext

  往ContextMap中存入数据:

public class UserAction extends ActionSupport {
public String index(){
ActionContext actionContext = ActionContext.getContext();
actionContext.put("contextMapKey","this is ContextMap value"); //底层:ActionContext.context.put()
return SUCCESS;
}
}

  往ServletContext域中存入数据:application,

  取值:#ContextMap的key.key

<s:property value="#application.application1" />

5.ValueStack

  值栈中的数据不需要使用#访问。而ContextMap中的Value需要使用#Key

  valueStack是一个List集合

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.opensymphony.xwork2.util; import java.util.Map; public interface ValueStack {
String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
String REPORT_ERRORS_ON_NO_PROP = "com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp"; Map<String, Object> getContext(); void setDefaultType(Class var1); void setExprOverrides(Map<Object, Object> var1); Map<Object, Object> getExprOverrides(); CompoundRoot getRoot(); void setValue(String var1, Object var2); void setParameter(String var1, Object var2); void setValue(String var1, Object var2, boolean var3); String findString(String var1); String findString(String var1, boolean var2); Object findValue(String var1); Object findValue(String var1, boolean var2); Object findValue(String var1, Class var2); Object findValue(String var1, Class var2, boolean var3); Object peek(); Object pop(); void push(Object var1); void set(String var1, Object var2); int size();
}

ValueStack.java

方法:

  

  OGNLValueStack:继承ValueStack

   CompoundRoot root;
public Object peek() {
return this.root.peek();
} public Object pop() {
return this.root.pop();
} public void push(Object o) {
this.root.push(o);
}

  使用valueStack存入数据:User1Action.java

public class User1Action extends ActionSupport {
public String login(){
ActionContext actionContext = ActionContext.getContext();
//valueStack
ValueStack valueStack = actionContext.getValueStack();
Student student = new Student();
student.setId(1);
student.setUsername("张三");
student.setAge(21);
valueStack.push(student);
return SUCCESS;
}
}

  不建议把Map和List加到值栈中,建议存入到ContextMap。对于POJO建议存入到值栈中

取值:先从栈顶找,有没有username的对象,再看有没有username的属性

 <s:property value="username" />
栈顶:
<s:property value="[0].username" />
<s:property value="[1].username" />
OGNL通过ValueStack.findValue方法找值

6.struts2中使用EL

  (1)struts2中的EL :由于request对象被增强了,valueStack和ContextMap本质上是存入到request对象中,因此ActionContext是每次请求实例化一次。

page --> request  --> valueStack -->  ContextMap --> session --> application

案例:

public class User2Action extends ActionSupport {
public String index(){
ActionContext actionContext = ActionContext.getContext();
//valueStack
Student student1 = new Student();
student1.setId(1);
student1.setUsername("张三");
student1.setAge(21); Student student2 = new Student();
student2.setId(3);
student2.setUsername("张三2");
student2.setAge(23); Map<String, Object> contextMap = actionContext.getContextMap();
List<Student> list = new ArrayList<Student>();
list.add(student1);
list.add(student2);
contextMap.put("students", list);
return SUCCESS;
}
}

User2Action

EL :查找顺序 page>request>valueStack>ContextMap>session >application

 <table border="1">
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
<c:forEach items="${students}" var="s">
<tr>
<td>${s.username}</td>
<td>${s.age}</td>
</tr>
</c:forEach> </table>

  

end

OGNL,表达式上下文ContextMap的更多相关文章

  1. Ognl表达式基本原理和使用方法

    Ognl表达式基本原理和使用方法 1.Ognl表达式语言 1.1.概述 OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个 ...

  2. 关于Struts2中的值栈与OGNL表达式

    1.1.1    OGNL概述: Object Graphic Navigation Language(对象图导航语言)的缩写 * EL     :OGNL比EL功能强大很多倍. 它是一个开源项目. ...

  3. Struts2之 OGNL表达式和值栈

    技术分析之OGNL表达式概述(了解)        1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写        * 所谓对象图,即以任意 ...

  4. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  5. struts2 OGNL表达式

    一.OGNL OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对 ...

  6. OGNL表达式

    一.什么是OGNL,有什么特点?     OGNL(Object-Graph Navigation Language),大概可以理解为:对象图形化导航语言.是一种可以方便地操作对象属性的开源表达式语言 ...

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

    一.什么是OGNL,有什么特点? OGNL(Object-Graph Navigation Language),大概可以理解为:对象图形化导航语言.是一种可以方便地操作对象属性的开源表达式语言.OGN ...

  8. JSTL标签,EL表达式,OGNL表达式,struts2标签 汇总

    一下纯属个人总结摘抄,总结一起方便查看,解决疑问,有遗漏或错误,还请指出.       1,JSTL标签总结: a).JSTL标签有什么用?          JSTL是由JCP(Java Commu ...

  9. struts2视频学习笔记 28(OGNL表达式)

    课时28 OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts 2框架使用OGNL作为默认的表达式语 ...

随机推荐

  1. 采样器----Debug Sampler

    Debug Sampler可以产生所有JMeter变量和属性的样本,可以在View Tree Result的响应中查看变量的值,此取样器在调试脚本阶段可以很方便的看到变量的值,在正式运行脚本的过程中应 ...

  2. 20165219 2017-2018-2 《Java程序设计》第6周学习总结

    20165219 2017-2018-2 <Java程序设计>第6周学习总结 教材学习内容小结 第八章 String类 常用方法 public int length() 求字符串长度 pu ...

  3. nginx负载均衡tomcat和配置ssl

    目录 tomcat 组件功能 engine host context connector service server valve logger realm UserDatabaseRealm 工作流 ...

  4. bzoj1798维护序列

    题目链接 暴力数据结构之线段树$qwq$ 裸题直接敲板子 忘了啥时候写的了$qwq$ 直接上代码吧 /************************************************* ...

  5. Date时间格式的转换以及一些用法

    import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.u ...

  6. Java网络编程客户端和服务器通信

    在java网络编程中,客户端和服务器的通信例子: 先来服务器监听的代码 package com.server; import java.io.IOException; import java.io.O ...

  7. mysql的主从与读写分离

    首先我们搭建两个MySQL服务器,这一步地球人都知道. 搭建好后,把两个数据库的数据同步.这一步就要用到我们前面说的备份和还原了.注意:我们只要同步MySQL以外的数据,MySQL库中的帐号密码肯定不 ...

  8. python学习之路---day03

    一:数据类型转换 1:bool-->int 将bool转成 int型 True 是1 False是0 a=True c=int(a) print(c) b=False d=int(b) prin ...

  9. table中thead固定一直在最上面

    <link rel="shortcut icon" href="favicon.ico"> <link href="css/boot ...

  10. vi vim 查找替换

    #查找# / 光标向下查找 ?光标向上查找 按键盘n,继续查找 #替换# :s/hello/test/ 替换光标所在行第一个hello为test :s/hello/test/g  替换光标所在行所有h ...