Struts2第三天

上次课回顾

Struts2的Servlet的API的访问

  • 完全解耦合的方式:ActionContext对象(基于值栈)
  • 使用原生的方式:ServletActionContext对象
  • 接口注入的方式:实现ServletRequestAware,ServletContext Aware,ServletResponseAware

Struts2的结果页面配置

  • 结果页面类型
    • 全局结果页面
    • 局部结果页面
  • 结果页面配置
    • name属性
    • type属性
      • dispatcher :默认值,转发
      • redirect :重定向
      • chain :转发到Action
      • redirectAction:重定向到Action

Struts2的数据的封装

  • 属性驱动
    • 一种:提供set方法的方式
    • 二种:页面提供OGNL表达式的方式
  • 模型驱动
    • 三种:模型驱动的方式

Struts2的复杂类型的数据封装

  • 封装到List集合中
  • 封装到Map集合中

2、OGNL表达式

2.1 OGNL概述

对象导航图语言(Object Graph Navigation Language),简称OGNL,是应用于Java中的一个开源的表达式语言(Expression Language),它被集成在Struts2等框架中,作用是对数据进行访问,它拥有类型转换、访问对象方法、操作集合对象等功能。

  • OGNL:对象图导航语言,比EL表达式强大很多倍的语言
    • EL:从域对象中获取数据,从EL的11个对象中获取数据
    • OGNL:调用对象的方法,获取Struts2的值栈的数据。

2.2 OGNL使用的要素

  • 表达式
  • 根对象
  • Context对象

2.3 OGNL的java环境下的入门(了解)

  • 访问对象的方法
//OGNL调用对象的额方法
@Test
public void demo1() throws OgnlException {
	//获得context
	OgnlContext context = new OgnlContext();
	//获得根对象
	Object root = context.getRoot();
	//执行表达式
	Object obj = Ognl.getValue("'helloWorld'.length()", context, root);
	System.out.println(obj);
}
  • 访问对象的静态方法
@Test
public void demo2() throws OgnlException {
	//获得context对象
	OgnlContext context = new OgnlContext();
	//获得根对象
	Object root = context.getRoot();
	//执行表达式:@类名@方法名
	Object obj =  Ognl.getValue("@java.lang.Math@random()",context, root);
	System.out.println(obj);
}
  • 获得Root中的数据
//访问Root中的数据,不需要加#
@Test
public void demo3() throws OgnlException {
	//获得context对象
	OgnlContext context = new OgnlContext();
	context.setRoot(new User("hamza","666"));
	//获得根对象
	Object root = context.getRoot();
	//执行表达式
	Object username = Ognl.getValue("name", context, root);
	Object pwd = Ognl.getValue("password", context, root);
		
	System.out.println(username+"-->"+pwd);
}
  • 获得OGNLContext中的数据
//访问context中的数据,需要加#
@Test
public void demo4() throws OgnlException {
	//获得context对象
	OgnlContext context = new OgnlContext();
	//获得根对象
	Object root = context.getRoot();
	//向context中存入数据
	context.put("name", "张三");
	//执行表达式
	Object name = Ognl.getValue("#name", context, root);
		
	System.out.println(name);
}

2.4 OGNL 的Struts2环境入门

  • 访问对象的方法
<h3>调用对象的方法</h3>
<s:property value="'struts'.length()"/>
  • 访问对象的静态方法
<h3>调用对象的静态方法</h3>
<!-- 静态方法访问在struts2中是默认关闭的,要使用就得开启一个常量 -->
<s:property value="@java.lang.Math@random()"/>
<!-- 开启静态方法访问 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

3、值栈

3.1 值栈的概述

3.1.1 什么是值栈

Struts2将XWork对Ognl的扩展这一套机制封装起来,这个对象叫ValueStack。
ValueStack实际上就是一个容器。它由Struts框架创建,当前端页面如jsp发送一个请求时,Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶。

  • ValueStack类似于一个数据中转站(Struts2的框架当中的数据就都保存到了ValueStack中)
    • ValueStack接口,实现类OgnlValueStack对象
    • ValueStack贯穿整个Action的生命周期。(Action一旦创建你了,框架就会创建一个ValueStack对象)
3.1.2 值栈的内部结构
  • ValueStack中有两个主要的区域:
    • root区域 :其实就是一个ArrayList。里面一般放置对象。获取root的数据不需要加#
    • context区域 :其实就是一个Map。里面放置的是web开发的常用的对象数据的引用。获取context数据需要加#
      • request
      • session
      • application
      • parameter
      • attr
  • 所说的操作值栈,通常指的是操作ValueStack中的root区域。
3.1.3 值栈与ActionContext的关系
  • ServletContext :Servlet的上下文
  • ActionContext :Action的上下文
    • 通过源代码查看到:当请求过来的时候,执行过滤器中doFilter方法,在这个方法中创建ActionContext,在创建ActionContext过程中,创建ValueStack对象,将ValueStack对象传递给ActionContext对象。所以可通过ActionContext获取值栈对象。
    • ActionContext对象之所以能够访问Servlet的API(访问是域对象的数据),因为在其内部有值栈的引用。

3.2 获得值栈

  • 通过ActionContext对象获得值栈
//一种:通过ActionContext获得
ValueStack valueStack = ActionContext.getContext().getValueStack();
  • 在Struts2的内部,将值栈存入request中一份
//二种:通过request对象获得
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest()
            .getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
//一个Action的实例,只会创建一个ValueStack的对象
System.out.println(valueStack == valueStack2);
//结果为true

3.3 操作值栈—向值栈中存入数据

  • 一种:在Action中提供属性的get方法方式
public class ValueStackDemo3 extends ActionSupport{
	private User user;
	public User getUser() {
		return user;
	}
	
	@Override
	public String execute() throws Exception {
		//向ValueStack中存入数据
		user = new User("张三","123");
		return SUCCESS;
	}
}

在页面中用OGNL表达式获取

<s:property value="user.name"/>
  • 二种:ValueStack中本身的方法方式
@Override
	public String execute() throws Exception {
		//向ValueStack中存入数据
		//获得值栈对象
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		//使用push(Object obj); set(String key,Object obj)
		User user = new User("张三","123456");
		valueStack.push(user);
		valueStack.set("laqin", "laqin");	//创建了一个Map,将这个Map压入到栈顶
		return SUCCESS;
	}
<!-- 方式二的获取:调用ValueStack本身的方法 -->
<s:property value="username"/>
<s:property value="pwd"/>
<s:property value="laqin"/>

3.4 获取值栈的数据

  • 获取值栈中的数据就是在页面中使用OGNL表达式即可
    • 获取root的数据:不需要加#
<!-- 获取一个对象 -->
<s:property value="name"/>
<s:property value="pwd"/>
<!--  获取集合中的对象-->
<s:property value="list[0].name"/><br/>
<s:property value="list[0].pwd"/><br/>
<s:property value="list[1].name"/><br/>
<s:property value="list[1].pwd"/><br/>
<s:property value="list[2].name"/><br/>
<s:property value="list[2].pwd"/><br/>
<s:property value="list[3].name"/><br/>
<s:property value="list[3].pwd"/><br/>

获取context的数据

<!-- 获取context中的数据 -->
<s:property value="#request.name"/>
<s:property value="#session.name"/>
<s:property value="#application.name"/>
<s:property value="#attr.name"/>
3.4.1 EL为何能访问值栈的数据
  • 因为Struts2的框架底层对request.getAttribute(String name)进行了增强

4、OGNL中特殊字符

4.1 #号

  • 获取context的数据
<%
	request.setAttribute("name", "张三");
%>
<s:property value="#request.name"/>
  • 可以使用#来构建Map集合
<h3>构建Map集合</h3>
<!-- 遍历值栈中的数据 -->
<s:iterator value="list">
	<s:property value="name"/>
</s:iterator>
<s:iterator var="i" value="{'aa','bb','cc','dd'}">
	<s:property value="i"/> -- <s:property value="#"/><br/>
</s:iterator>
<!-- Map集合-->
<s:iterator var="entry" value="#{'name':'张三'},'age':'23' }">
	<s:property value="key"/> ----><s:property value="value"/><br/>
	<s:property value="#entry.key"/> ----><s:property value="#entry.value"/><br/>
</s:iterator>

4.2 %号

  • 强制解析OGNL
<h2>%号的用法</h2>
<%
	request.setAttribute("name", "牛魔王");
%>
姓名:<s:textfield name="name" value="%{#request.name}"/>
  • 强制不解析OGNL

4.3 %号

  • 在配置文件中使用OGNL
    • 属性文件
      • 国家化地方
        • message_zh_CN.properties
          • user.login=登录
          • userwelcome=欢迎,${#session.username}
        • message_en_US.properties
          • userlogin=Login
          • userwelcome=欢迎,${#session.username}
    • xml文件
      • 文件下载
        • 配置
<action name="download" class="xxx.DownloadAction">
    <result type="stream">
        <param name="Content-Type">文件类型</param>  
        <param name="Content-Disposition">attachment:filename=${文件名}</param>  
    </result>
</action>

总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值