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. HDP 中 yarn 和 MR2 的配置

    以下说明均以集群中 slave 结点的配置为 48G内存,12块硬盘,12核(core) CPU 为例. 在 Yarn 中,一个 Container 是一个基础的包含内存和CPU 的单元.为了较好的平 ...

  2. 单机,伪分布式,完全分布式-----搭建Hadoop大数据平台

    Hadoop大数据——随着计算机技术的发展,互联网的普及,信息的积累已经到了一个非常庞大的地步,信息的增长也在不断的加快.信息更是爆炸性增长,收集,检索,统计这些信息越发困难,必须使用新的技术来解决这 ...

  3. Liunx常用的100条命令汇存

    1.关机 shutdown -h now 立刻关机 poweroff shutdown -r now 立刻重启 reboot logout 注销 2.进入图形界面 startx 3.vi编辑器 [vi ...

  4. MySQL 学习笔记(三):完整性和触发器设计

    (一)完整性设计 方法一.在设计表时定义约束 删除数据库school,建立新数据库school1 drop database school; create database school; use s ...

  5. 【BZOJ2839】集合计数 容斥原理+组合数

    Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 它们的交集的元素个数为K,求取法的方案数,答案模1000000007 ...

  6. 洛谷P4502 [ZJOI2018]保镖(计算几何+三维凸包)

    题面 传送门 题解 我对计蒜几盒一无所知 顺便\(xzy\)巨巨好强 前置芝士 三维凸包 啥?你不会三维凸包?快去把板子写了->这里 欧拉公式 \[V-E+F=2\] \(V:vertex\)顶 ...

  7. 犯得错误QAQ

    1.十年OI一场空,不开longlong见祖宗(丢过150分) 2.计算完了再开数组,开的足足的.不要少开0:(丢过一共200分) 3.最大值,最小值一定开成7个f.(丢了20分). 4.freope ...

  8. 使用原生实现jquery中的css方法

    由于jquery放在mobile页面上,有时候还是显得有点大,所以今天尝试使用原生来开发,但是习惯了jquery之后,转用原生开发之后,发现原生中,找不到可以替代jquery的css方法,于是对原生的 ...

  9. SDUT OJ 数据结构上机测试1:顺序表的应用

    数据结构上机测试1:顺序表的应用 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descri ...

  10. 蓝牙4.0BLE抓包(三) – 扫描请求和扫描响应

    版权声明:本文为博主原创文章,转载请注明作者和出处.    作者:强光手电[艾克姆科技-无线事业部] 1. 扫描请求和扫描响应 广播包含扫描请求SCAN_REQ和扫描响应SCAN_RSP. 扫描请求: ...