Struts框架笔记03

mac2022-06-30  19

目录

1. OGNL 1.1 OGNL概述 1.1 什么是OGNL1.1.2 OGNL的优势1.1.2 OGNL使用的要素1.2 OGNL的Java环境入门【了解】 1.2.1 访问对象的方法1.2.2 访问对象的静态方法1.2.3 获得Root中的数据1.2.4 获得OgnlContext中的数据1.3 OGNL的Struts2的环境入门 1.3.1 访问对象的方法1.3.2 访问对象的静态方法2. 值栈 2. 1什么是值栈2.2 值栈的内部结构2.3 值栈与ActionContext的关系2.4 获得值栈2.5 操作值栈 2.5.1 方式一:在Action中提供属性的get方法的方式2.5.2 使用ValueStack中本身的方法的方式2.6 获得值栈数据2.7 EL为何能访问值栈的数据3. OGNL中的特殊字符 3.1 #号 3.1.1 获取context的数据3.1.2 使用#号构建List或map集合3.2 %号3.3 $号

1. OGNL

1.1 OGNL概述

1.1 什么是OGNL

OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。OGNL:对象导航语言,可以方便地操作对象属性的开源表达式语言,使页面更简洁;比EL表达式强大很多倍。可以调用Struts2的值栈的数据。OGNL其实第三方的表达式语言。EL:从域对象中获取数据,或者从EL的11个对象中获取。

1.1.2 OGNL的优势

Struts 2默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:

支持对象方法调用,如xxx.doSomeSpecial();

支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;

支持赋值操作和表达式串联,如price=100, discount=0.8, calculatePrice(price*discount),这个表达式会返回80;

访问OGNL上下文(OGNL context)和ActionContext;

操作集合对象。

可以直接new一个对象

1.1.2 OGNL使用的要素

表达式根对象Context对象

1.2 OGNL的Java环境入门【了解】

1.2.1 访问对象的方法

@Test // OGNL调用对象的方法 public void test1() throws OgnlException { // 获得context OgnlContext context = new OgnlContext(); // 获得根对象 Object root = context.getRoot(); // 执行表达式 Object object = Ognl.getValue("'helloworld'.length()", context, root); System.out.println(object);//10 }

1.2.2 访问对象的静态方法

@Test // OGNL访问对象的静态方法 public void test2() throws OgnlException { // 获得context OgnlContext context = new OgnlContext(); // 获得根对象 Object root = context.getRoot(); // 执行表达式@类名@方法名 Object object = Ognl.getValue("@java.lang.Math@random()", context, root); System.out.println(object);// 0-1的随机数 }

1.2.3 获得Root中的数据

@Test // 访问Root中的数据,不需要加# public void test3() throws OgnlException { // 获得context OgnlContext context = new OgnlContext(); // 执行表达式 User user = new User("aaa", "123"); context.setRoot(user); // 获得根对象 Object root = context.getRoot(); Object username = Ognl.getValue("username", context,root); Object password = Ognl.getValue("password", context,root); System.out.println(username+" "+password); }

1.2.4 获得OgnlContext中的数据

@Test // 访问Context中的数据,需要加# public void test4() throws OgnlException { // 获得context OgnlContext context = new OgnlContext(); // 获得根对象 Object root = context.getRoot(); // 向context中存入数据 context.put("name", "张三"); // 执行表达式 Object object = Ognl.getValue("#name", context, root); System.out.println(object); }

1.3 OGNL的Struts2的环境入门

1.3.1 访问对象的方法

在web.xml文件中配置核心过滤器 <!-- 配置核心过滤器 --> <filter> <filter-name>struts</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 引入struts核心配置文件编写一个JSP../WebContent/demo1/test.jsp,引入struts的标签库 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>OGNL在Struts2环境中的入门</h1> <h3>调用对象的方法</h3> <s:property value="'struts'.length()"/> </body> </html>

1.3.2 访问对象的静态方法

静态方法访问在Struts2中默认是关闭的,需要手动开启一个常量在配置文件中开启常量 <struts> <!-- 开启静态方法 --> <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant> </struts> JSP <h1>OGNL在Struts2环境中的入门</h1> <h3>调用对象的方法</h3> <s:property value="'struts'.length()"/> <h3>调用对象的静态方法</h3> <!-- 静态方法访问在Struts2中默认是关闭的,需要手动开启一个常量 --> <s:property value="@java.lang.Math@random()"/> 测试:访问jsp页面,能正常显示struts的长度和产生的随机数

2. 值栈

2. 1什么是值栈

值栈ValueStack是Struts的一个接口。OgnlValueStack是ValueStack的实现类,客户端发送一个请求struts2架构会创建一个action实例同时创建一个OgnlValueStack值栈实例,OgnlValueStack贯穿整个Action生命周期,struts2中使用OGNL将请求Action的参数封装为对象存储到值栈中,并通过OGNL表达式读取值栈中的对象属性值。值栈其实类似于一个数据中转站,Struts2中的数据都保存到了值栈中。request域中的数据只能在jsp页面中取出,但是值栈中的数据可以在jsp页面、Action、配置文件中取出。

2.2 值栈的内部结构

ValueStack中有两个主要的区域: root区域:其实就是一个ArrayList。里面一般放置对象。获取root数据需要加#。context区域:其实就是一个Map。放置的是web开发的常用对象数据的引用。获取context数据需要加#。 requestsessionapplicationattr所说的操作值栈,通常指的是操作ValueStack中的root区域。

2.3 值栈与ActionContext的关系

ActionContext:Action的上下文通过源码可以看到。当前请求过来的时候,执行过滤器中doFilter方法,在这个方法中创建ActionContext,在创建ActionContext过程中,也创建了ValueStack对象,并且将ValueStack对象传递给ActionContext对象。所以可以通过ActionContext获取值栈对象。ActionContext对象之所以能够访问Servlet的API(访问的是域对象的数据)是由于其内部有值栈的引用。

2.4 获得值栈

package com.itzhouq.struts.valueStack; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; /** * 获得值栈的方式 * @author itzhouq * */ public class ValueStackDemo1 extends ActionSupport { @Override public String execute() throws Exception { // 方式一: ValueStack valueStack1 = ActionContext.getContext().getValueStack(); // 方式二: ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack"); // 一个Action的实例,只会创建一个ValueStack的对象 System.out.println(valueStack1 == valueStack2);//true return NONE; } }

2.5 操作值栈

操作值栈----向值栈中存储数据

2.5.1 方式一:在Action中提供属性的get方法的方式

默认情况下,将Action对象压入到值栈。Action的属性也会在值栈中。

编写Action类ValueStackDemo2

package com.itzhouq.struts.valueStack; import com.itzhouq.struts.domain.User; import com.opensymphony.xwork2.ActionSupport; /** * 操作ValueStack,方式一:利用Action本身在值栈中的特性 * @author itzhouq * */ public class ValueStackDemo2 extends ActionSupport { private User user; public User getUser() { return user; } @Override public String execute() throws Exception { // 向ValueStack中存储数据 user = new User("李斌","456"); return SUCCESS; } }

在配置文件中配置

action name="valueStackDemo2" class="com.itzhouq.struts.valueStack.ValueStackDemo2"> <result>/demo1/success.jsp</result> </action>

跳转页面success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html> <html> <head> <meta 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"/> </body> </html>

访问http://localhost/Struts2_day03/valueStackDemo2.action

2.5.2 使用ValueStack中本身的方法的方式

编写Action类ValueStackDemo3

package com.itzhouq.struts.valueStack; import com.itzhouq.struts.domain.User; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; /** * 操作值栈:方式二:调用值栈中的方法实现 * @author itzhouq * */ public class ValueStackDemo3 extends ActionSupport{ @Override public String execute() throws Exception { // 向值栈中保存数据: // 获得值栈对象 ValueStack valueStack = ActionContext.getContext().getValueStack(); // 使用push(Object obj); set(String key, Object obj); User user = new User("李世民","26"); // 现在user在栈顶的位置 valueStack.push(user); valueStack.set("name", "赵子龙");// 创建一个Map集合,将Map压入到栈中 return super.execute(); } }

在配置文件中配置,跳转页面success.jsp

<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"/> <s:property value="name"/>

访问http://localhost/Struts2_day03/valueStackDemo3.action

2.6 获得值栈数据

获取值栈中的数据就是在页面中使用OGNL表达式 获取root的数据,不需要加#获取context中的数据,需要加#

编写Action了ValueStackDemo4

package com.itzhouq.struts.valueStack; import java.util.ArrayList; import java.util.List; import org.apache.struts2.ServletActionContext; import com.itzhouq.struts.domain.User; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; /** * 获取值栈的数据 * @author itzhouq * */ public class ValueStackDemo4 extends ActionSupport{ @Override public String execute() throws Exception { // 向值栈中保存一个对象 User user = new User("aaa", "111"); ActionContext.getContext().getValueStack().push(user); // 向值栈中保存一个集合 List<User> list = new ArrayList<User>(); list.add(new User("aaa","111111")); list.add(new User("bbb","222222")); list.add(new User("ccc","333333")); ActionContext.getContext().getValueStack().set("list", list); // 向context中存入数据 ServletActionContext.getRequest().setAttribute("name", "r李斌"); ServletActionContext.getRequest().getSession().setAttribute("name", "s赵红"); ServletActionContext.getServletContext().setAttribute("name", "a邓子龙"); return super.execute(); } }

在主配置文件中配置Demo4,编写跳转页面success2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>获取值栈的数据</h1> <s:debug></s:debug> <!--获取一个对象的数据 --> <s:property value="username"/> <s:property value="password"/> <br><br> <!-- 获取集合中数据 --> <s:property value="list[0].username"/> <s:property value="list[0].password"/><br> <s:property value="list[1].username"/> <s:property value="list[1].password"/><br> <s:property value="list[2].username"/> <s:property value="list[2].password"/><br> <br><br> <!-- 获取context中的数据 --> <s:property value="#request.name"/><br> <s:property value="#session.name"/><br> <s:property value="#application.name"/><br> </body> </html>

测试:访问http://localhost/Struts2_day03/valueStackDemo4.action

2.7 EL为何能访问值栈的数据

因为Struts2的框架的底层对request.getAttribute(String name);进行了增强。

3. OGNL中的特殊字符

3.1 #号

3.1.1 获取context的数据

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>#的用法</h1> <% request.setAttribute("name", "李斌"); %> <s:property value="#request.name"/> <hr> </body> </html> 在页面能获取到request中存储的数据

3.1.2 使用#号构建List或map集合

../WebContent/demo2/test.jsp <h3>构建list集合</h3> <s:iterator var="i" value="{'aa','bb','cc'}"> <s:property value="i"/> -- <s:property value="#i"/> <br> </s:iterator> <h3>构建Map集合1</h3> <s:iterator value="#{'aa':'11111', 'bb':'22222', 'cc':'33333' }"> <s:property value="key"/>--<s:property value="value"/><br> </s:iterator> <h3>构建Map集合2</h3> <s:iterator var="entry" value="#{'aa':'11111', 'bb':'22222', 'cc':'33333' }"> <s:property value="#entry.key"/>--<s:property value="#entry.value"/><br> </s:iterator> <h3>实例1</h3> <s:radio list="{'男', '女' }" name="sex1" label="性别"/><br> <h3>实例2</h3> <s:radio list="#{'1':'男','2': '女' }" name="sex2" label="性别"/>

访问http://localhost/Struts2_day03/demo2/test.jsp

3.2 %号

强制解析成OGNL表达式

../WebContent/demo2/test2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h3>%的使用</h3> <% request.setAttribute("name", "罩子龙"); %> 姓名:<s:textfield name="name" value="%{#request.name}"/> </body> </html> 访问:http://localhost/Struts2_day03/demo2/test2.jsp

3.3 $号

在配置文件中使用$。

转载于:https://www.cnblogs.com/itzhouq/p/Struts.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)