EL表达式(JSP)、OGNL表达式(Struts2标签库)介绍及struts2中View与Controller的数据交换

一.EL表达式

EL表达式全名为Expression Language,可用于JSP页面中取值。EL 语法很简单,它最大的特点就是使用上很方便。EL主要的语法结构:${sessionScope.user.sex},所有EL都是以${为起始、以}为结尾的。

1.使用EL表达式取域中的变量

EL 存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。若没有指定哪一个范围的username,它会先从Page 范围找,假如找不到,再依序到Request、Session、Application范围。假如途中找到username,就直接回传,不再继续找下去,但假如全部的范围都没有找到时,就回传null,当然EL表达式还会做出优化,页面上显示空白,而不是打印输出NULL。

属性范围EL中的名称
PagePageScope
RequestRequestScope
SessionSessionScope
ApplicationApplicationScope

我们也可以指定要取出哪一个范围的变量:

范例说明
${pageScope.username}取出Page范围的username变量
${requestScope.username}取出Request范围的username变量
${sessionScope.username}取出Session范围的username变量
${applicationScope.username}取出Application范围的username变量

其中,pageScope、requestScope、sessionScope和applicationScope都是EL 的隐含对象,由它们的名称可以很容易猜出它们所代表的意思,例如:${sessionScope.username}是取出Session范围的username 变量。

JSP有9个隐含对象,而EL也有自己的隐含对象。EL隐含对象总共有11 个
在这里插入图片描述

2.属性(Attribute)与范围(Scope)

与范围有关的EL 隐含对象包含以下四个:pageScope、requestScope、sessionScope 和applicationScope,它们基本上就和JSP的pageContext、request、session和application一样,所以这里只稍略说明。
不过必须注意的是,这四个隐含对象只能用来取得范围属性值,即JSP中的getAttribute(String name),却不能取得其他相关信息,例如:JSP中的request对象除可以存取属性之外,还可以取得用户的请求参数或表头信息等等。但是在EL中,它就只能单纯用来取得对应范围的属性值,

例如:我们要在session 中储存一个属性,它的名称为username,在JSP 中使用session.getAttribute(“username”)来取得username 的值,但是在EL中,则是使用${sessionScope.username}来取得其值的。

3. '.'与 ‘[ ]’ 运算符

EL 提供 . 和 [ ] 两种运算符来导航数据。下列两者所代表的意思是一样的:${sessionScope.user.sex}等于${sessionScope.user[“sex”]}。

. 和 [ ] 也可以同时混合使用,如下:
${sessionScope.shoppingCart[0].price},回传结果为shoppingCart中第一项物品的价格。不过,以下两种情况,两者会有差异:

(1) 当要存取的属性名称中包含一些特殊字符,如. 或 – 等并非字母或数字的符号,就一定要使用 [ ],

例如:${user.My-Name }

上述是不正确的方式,应当改为:${user[“My-Name”] }

(2) 我们来考虑下列情况:

${sessionScope.user[data]}

此时,data 是一个变量,假若data的值为"sex"时,那上述的例子等于${sessionScope.user.sex};假若data 的值为"name"时,它就等于${sessionScope.user.name}。因此,如果要动态取值时,就可以用上述的方法来做,但.无法做到动态取值。

4.示例

(1)在Controller层的某个action中将一个字符串放入Session域中:

String userName="hellow,world!";
ActionContext.getContext().getSession().put("username", userName);

在View层的某个jsp页面中使用EL语句取出username对象:

<p>${username}</p>
或
<p>${sessionScope.username}</p>

(2)将相同字符串放入Request域:

ServletActionContext.getRequest().setAttribute("username1", userName); 

在jsp页面中使用EL语句取出username变量

<p>${username1}</p>
或
<p>${requestScope.username1}</p>

参考https://www.cnblogs.com/czs1982/p/3966748.html

二、OGNL表达式

1.Ognl表达式语言的作用

  • jsp页面取值用
  • EL表达式语言,也用于页面取值,是jsp页面取值的标准(默认就可以使用)
  • Ognl表达式语言,Struts标签默认支持的表达式语言,必须配置Struts标签用,不能
  • 开Struts标签直接使用,就是说Ognl必须在Struts中使用
  • 对比来看,EL使用范围更广,项目中不限制使用哪一种,哪一种熟悉就使用哪一种

说明:在Struts2的View层的页面使用OGNL表达式获取数据时,其实就是将ValueStack(值栈)中的数据取出来。因为在Struts2中利用Ognl时,实际上使用的是实现了该接口的OgnlValueStack类,故获取数据是通过valueStack实现的。但因为ValueStack中仍存放有request、session、application、attr、parameters(传递相关参数,请求的相关参数?)等对象的引用(context中的Map集合),故仍可通过OGNL获取web中域的相关参数。

2.OGNL表达式的使用规则

  • OGNL表达式要与struts2标签库中的标签配合使用,JSP页面中需要引入struts2标签库,故没有EL表达式适用范围广
  • 使用Ognl表达式语言取值,如果取根元素的值,不用#号
  • 使用Ognl表达式语言取值,如果取非根元素的值,必须用#号
  • Ognl可以调用静态方法

3.ValueStack中的根元素与非根元素

根元素:root 其实就是一个ArrayList 就是action 的相关信息,我们在controller层中放入值栈的数据便在root中(一般操作root)。

非根元素(context):context 其实就是一个Map 各种映射常见的web对象,等价于ognlContext 上下文 。

root结构:
在这里插入图片描述
context结构:在这里插入图片描述

4.示例

(1) 在Controller层某个action的ValueStack中存入数据:

String userName="hellow,world!";
ActionContext.getContext().getValueStack().set("username2", userName);

并使用OGNL表达式在View层的JSP页面(引入Struts2标签库)中读取该数据:

<p><s:property value="username2"/></p>		//与<s:property>标签配合使用,根元素无需“#”号

(2) 将相同字符串放入Request域:

ServletActionContext.getRequest().setAttribute("username3", userName);

使用OGNL表达式在View层的JSP页面(引入Struts2标签库)中读取该数据:

<p><s:property value="#request.username3"/></p>		//与<s:property>标签配合使用,request在context中,非根元素,使用需加“#”号

参考https://www.cnblogs.com/cenyu/p/6233942.html#autoid-1-0-0
https://blog.csdn.net/qq_37248648/article/details/73011644

二、JSP作用域及其EL表达式对应内置对象

1.JSP作用域内置对象

在这里插入图片描述
内置对象(又叫隐含对象)特点:

  1. 由JSP规范提供,不用编写者实例化。
  2. 通过Web容器实现和管理
  3. 所有JSP页面均可使用
  4. 只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%>或<%使用内置对象%>)

request对象
request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。

response对象
response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。

session对象
session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。

application对象
对应ServletContext,application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。

pageContext 对象
pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。

page 对象
page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。
在这里插入图片描述
示例:在JSP页面中获取页面(page)内的参数

<%@ page language="java" contentType="text/html;charSet=GBK" %>
<%@ page import="java.lang.Object" %>
<html>
    <body>
        <center><h3>Page内置对象的实例</h3></center>
        <%!Object obj; %> <!-- 对象申明 -->
        getClass:<%=page.getClass() %>
        hashCode:<%=page.hashCode()%>
        toString:<%=page.toString()%>
        equals:<%=page.equals(obj) %>
        equlas2:<%=page.equals(this) %>
    </body>
</html>

2.EL表达式内置对象

上述域对象需要在JSP页面中嵌入java语句获得,使用较为麻烦。那么我们是否能通过表达形式较为简单的EL表达式来获得不同的域对象中的参数?答案是肯定的,不过在EL表达式中不同的域对象是用pageScope、requstScope、sessionScope、applicationScope、pageContext等来命名的,分别对应上述的pageContext、request、session、application、pageContext等域对象。
(1)pageScope:获取jsp中pageContext域属性,相当于pageContext.getAttribute(“xxx”)
(2)requestScope:获取request域属性,相当于request.getAttribute(“xxx”)
(3)sessionScope:获取session域属性,相当于session.getAttribute(“xxx”)
(4)applicationScope:获取application域属性,相当于application.getAttribute(“xxx”)
(5)cookie:用于获取cookie,Map<String,Cookie>,其中key是cookie的name,value是cookie对象,例如${cookie.JSESSIONID.value }就是获取sessionId
(6)pageContext:可以获取JSP九大内置对象,相当于使用该对象调用getxxx()方法,例如pageContext.getRequest()可以写为${pageContext.request)。

示例:使用EL表达式获取域对象参数

  <c:forEach items="${requestScope['list']}" var="service" varStatus="st">
    <c:if test="${pageScope['st'].index % 2 == 0 && pageScope['st'].index  > 0}">
       测试
    </c:if>
    <c:if test="${pageScope['service'].字段信息 == 0 }">
      显示
    </c:if>
  </c:forEach>
  <span>${sessionScope['session'].字段信息}</span>

参考https://my.oschina.net/u/3805464/blog/1813805

三、struts2中View层与Controller层的数据交换

1.jsp->Action

模型驱动、继承ActionSupport(传输基本数据类型、复合类型对象包含很多数据字段,无法在JSP中组合传输到action中)、request对象、好像其他域对象也是可以的,需要查阅资料。

2.Action->jsp

模型驱动、继承ActionSupport、域对象(Request、Session、Application)、值栈(ValueStack)、cookie。

Struts2中实现模型驱动传参(可双向传递数据):
在controller中实现ModelDriven,在View的JSP中使用OGNL表达式:
<s:property value=”model.username”>获取参数。注意model后直接跟须需获得的变量名称,无需先获得user(model.user.username)。

3.Struts2中继承ActionSupport传参

Controller中的Action继承ActionSupport类,将需要在Controller层获取或需要写到View层的对象(对象名与JSP中的变量名保持一致)生成get(在Action中获取JSP变量)和set(将Action中变量传递到JSP中)方法。

使用域对象request(单次请求)、session(跨请求)、application以及值栈(ValueStack):
Request、session、application、valuestack均能在action->JSP传输数据时发挥作用,但个人觉得在JSP->action时,除了上述的两种方法外(模型驱动以及继承ActionSupport),域对象中有request等(其他域对象如何在JSP中记录页面数据,需要查询)能承担任务。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值