之前我们做的查询列表用的是EL和JSTL来完成的,这样并不好,因为struts2里面有自己的表达式语言和存取值的方式,下面就来看一下。
OGNL的概述
什么是OGNL?
OGNL:对象图导航语言,是一门功能强大的表达式语言。
OGNL的功能或作用:
Struts2默认的表达式语言就是OGNL,他支持:
1.对象方法的调用
2.类静态方法调用和值访问
3.赋值操作和表达式串联
4.访问ActionContext和OgnlContext数据
5.操作集合对象等
OGNL的三要素:
1.表达式(Expression) 核心,做什么,规定了操作类型和内容;
2.根对象(Root Object) 对谁操作,以任意一个对象为根,通过OGNL可以访问与这个对象关联的其他对象;
3.上下文环境(Context),在哪里进行,Context是一个Map类型对象,在表达式中访问Context中的对象,需要用“#对象名称”的形式。
OGNL的入门
- OGNL访问对象的方法
package com.wangshi.struts.ognl;
import org.junit.Test;
import ognl.Ognl;
import ognl.OgnlContext;
/**
* @author wanghaichaun
*OGNL的入门
*/
public class OgnlDemo01 {
@Test
//ognl调用对象的方法
public void demo01() throws Exception {
//获得上下文Context
OgnlContext context = new OgnlContext();
//得到根对象
Object root = context.getRoot();
//获取值 'helloworld'.length()就是表达式,结果是 10
Object obj = Ognl.getValue("'helloworld'.length()",context, root);
System.out.println(obj);
}
}
- 访问对象的静态方法,执行表达式:@类名@方法名
@Test
//访问对象的静态方法
public void demo02() throws Exception{
//获取context 上下文
OgnlContext context = new OgnlContext();
//得到根对象
Object root = context.getRoot();
//取值,执行表达式:@类名@方法名
Object obj = Ognl.getValue("@java.lang.Math@random()",context, root);
System.out.println(obj);
}
- OGNL获取Root数据
@Test
//OGNL获取数据
public void demo03() throws OgnlException{
//获得Context
OgnlContext context = new OgnlContext();
//在User类中获取ognlcontext中的数据:
//获得根对象
User user = new User("啦啦啦","12345");
context.setRoot(user);
//执行表达式
Object username = Ognl.getValue("username",context, context.getRoot());
Object password = Ognl.getValue("password",context, context.getRoot());
System.out.println(username+"==="+password);
}
- OGNL获取context数据
@Test
//OGNL获取context数据
public void demo04() throws OgnlException{
//获得Context
OgnlContext context = new OgnlContext();
//得到根
Object root = context.getRoot();
//获取值
context.put("username", "呦西");
//执行表达式
Object obj = Ognl.getValue("#username",context, root);
System.out.println(obj);
}
OGNL独立的表达式:
Java环境下入门
Struts2环境下入门
jsp页面并且配置struts2环境,静态方法访问在struts2中默认是关闭的,记得在default.properyies中开启
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!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>Insert title here</title>
</head>
<body>
<h1>OGNL在Struts2环境中的入门</h1>
<s:property value="'struts'.length()"/>
<h1>调用静态的方法</h1>
<!-- 静态方法访问在struts2中默认是关闭的。开启了一个常量 -->
<s:property value="@java.lang.Math@random()"/>
</body>
</html>
值栈的概述
ValueStack:
是一个接口,实现类OgnlValueStack;
是数据的中转站,贯穿了整个Action,有一个Action的实例,就会创建一个ValueStack对象。
值栈的内部结构:
ValueStack中有两个主要的区域:
Root :CompoundRoot,就是一个ArrayList,里面一般放置对象。获取Root的数据不需要加#。
Context :OgnlContext,就是一个Map,里面放置是web开发的常用的对象数据的引用。获取Context的数据需要加#。
package com.wangshi.struts.valuestack;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @author wanghaichaun
*ValueStack的内部结构
*/
public class ValueStackDemo01 extends ActionSupport {
@SuppressWarnings("unused")
@Override
public String execute() throws Exception {
//获得值栈
ValueStack valueStack = ActionContext.getContext().getValueStack();
return SUCCESS;
}
}
Context :OgnlContext的上下文,存储的引用:
parameters:map中包含的当前请求的请求参数;
request:map中包含当前request对象中的所有属性;
session:map中包含当前session对象中的所有属性;
application:map中包含当前application对象中的所有属性;
attr:该map 按顺序来检索某个属性:request,session,application
所说的操作值栈,通常就是值操作的ValueStack中的root区域.
ActionContext和值栈关系
ServletContext:Servlet的上下文。
ActionContext:Action的上下文。
1.通过源码查看到:当请求过来时,执行过滤器中的dofilter方法,在这个方法中创建ActionContext,
在创ActionContext过程中.创建ValueStack对象,将ValueStack对象传递给ActionContext对象,
所以可以通过ActionContext获取值栈对象.
2.ActionContext对象之所以能够访问Servlet的api(访问的是域对象的数据),因为在其内部有值栈的引用.
获得值栈对象
通过ActionContext获取
//1.通过ActionContext获得值栈
ValueStack valueStack = ActionContext.getContext().getValueStack();
通过request获取
//2.通过request对象获得
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest()
.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
操作值栈【向值栈中存入数据】
两种:
*在Action 中提供属性的get方法的方式
默认情况下,将action对象压入到值栈,action的属性也会在值栈中。
package com.wangshi.struts.valuestack;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import com.wangshi.struts.entity.User;
/**
* @author wanghaichaun
*在Action 中提供属性的get方法的方式,操作valueStack
*/
public class ValueStackDemo03 extends ActionSupport {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
//向valuestack中存值
user = new User("啊你有","123");
return SUCCESS;
}
}
*使用ValueStack 中本身的方法的方式
package com.wangshi.struts.valuestack;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import com.wangshi.struts.entity.User;
/**
* @author wanghaichaun
*方式二:使用ValueStack 中本身的方法的方式获取值
*/
public class ValueStackDemo04 extends ActionSupport {
@Override
public String execute() throws Exception {
//获取值栈对象
ValueStack valueStack = ActionContext.getContext().getValueStack();
//存值
User user = new User("看看","222");
//现在user在栈顶的位置
valueStack.push(user);
valueStack.set("username", "东东");//创建的是一个Map集合,将map压入到栈中;
valueStack.set("password", "123321");
return SUCCESS;
}
}
编写jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<h1>查看值栈的内部结构</h1>
<s:debug></s:debug>
<!-- 方式一:利用Action在值栈中的特性获取值 -->
<s:property value="user.username"/>
<s:property value="user.password"/>
<!-- 方式二:使用ValueStack 中本身的方法的方式获取值 -->
<s:property value="username"/>
<s:property value="password"/>
</body>
</html>
记得到struts.xml中配置
<?xml version="1.0" encoding="UTF-8"?>
<!-- struts的约束 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="demo01" extends="struts-default" namespace="/">
<action name="ValueStackDemo01" class="com.wangshi.struts.valuestack.ValueStackDemo01">
<result >/demo01/success.jsp</result>
</action>
<action name="ValueStackDemo02" class="com.wangshi.struts.valuestack.ValueStackDemo02">
</action>
<action name="ValueStackDemo03" class="com.wangshi.struts.valuestack.ValueStackDemo03">
<result >/demo01/success.jsp</result>
</action>
<action name="ValueStackDemo04" class="com.wangshi.struts.valuestack.ValueStackDemo04">
<result >/demo01/success.jsp</result>
</action>
</package>
</struts>
获取值栈的数据
获取Root中的数据,不需要加#
- 保存一个对象,获取ValueStack中的数据
- 保存一个list集合,获取ValueStack中的数据
获Context中的数据,需要加#
OGNL获取:<s:property value=”…”/>
EL获取值栈的数据
底层对Request对象的request.getAttribute(“”)方法进行了增强;
ONGL特殊字符
#号
获取context数据
构建map集合
<%@ 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>Insert title here</title>
</head>
<body>
<h1>#号的用法</h1>
<h3>获取Context的数据</h3>
<%
request.setAttribute("name", "拉丝");
%>
<s:property value="#request.name "/>
<h3>用于构建一个map集合:使用struts的UI标签的时候</h3>
<h3>list的集合</h3>
<s:iterator var="i" value="{'aa' ,'bb' ,' cc'}">
<s:property value="i"/>---<s:property value="#i"/><br>
</s:iterator>
<h3>map的集合</h3>
<s:iterator value="#{'aaa':'111', 'bbb':'222','ccc':'333'}" var="entry">
<s:property value="key"/>-----<s:property value="value"/><br>
<s:property value="#entry.key"/>-----<s:property value="#entry.value"/><br>
</s:iterator>
<s:radio list="#{'1':'男','2':'女' }" name="sex"></s:radio>
<s:debug></s:debug>
</body>
</html>
%号
强制解析OGNL
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<%
request.setAttribute("name", "王者归来");
%>
<h3>%号的用法:强制解析</h3>
<s:textfield name="name" value="%{#request.name}" />
<h3>%号的用法:不强制解析</h3>
<s:property value="%{'#request.name'}"/>
</body>
</html>
$号
在配置文件中使用OGNL
-
属性文件
国际化地方:*message zh CN.properties user.login=登录 user.welcome=欢迎,${#session.user.username} *message en US.properties user.login=Login user.welcome=welcome,${#session.user.username}
-
XML文件
文件下载:配置 <action name="download" class="xxx.DownloadAction"> <result type="stream"> <param name="Context-Disposition">文件类型</param> <param name="Context-Disposition">attachment;filename=${文件名}</param> </result> </action>
----------------------------------今天就了解到这里,有写的不好的地方请大家多多包涵!☻