1.在EL表达式中使用作用域变量

表达式语言对作用域变量的支持,以及它解析变量的方式都使它变得非常有用。

1.1 EL表达式的隐式变量

EL表达式的作用域中定义了11个隐式变量。

当EL表达式引用了一个变量时,EL求值程序将按照下面的流程解析变量:

  1. 检查该变量是否属于隐式变量。
  2. 如果变量不在11个隐式变量之中,EL求值程序将在页面作用域中找(PageContext.getAttribute("variable")
  3. 如果在页面作用域找不到,就找请求特性HttpServletRequest.getAttribute("variable")
  4. 如果找不到请求特性,就找会话特性HttpSession.getAttribute("variable")
  5. 如果找不到会话特性,就找应用特性ServletContext..getAttribute("variable")
  6. 在求值程序搜索完所有的位置之后,如果它未找到匹配变量名的隐式变量或者特性,它将会报出错误。
package com.wrox;

import java.util.Hashtable;
import java.util.Map; public class User
{
private long userId; private String username; private String firstName; private String lastName; private Map<String, Boolean> permissions = new Hashtable<>(); //...setter和getter方法
}
package com.wrox;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Hashtable; @SuppressWarnings("serial")
@WebServlet(
name = "profileServlet",
urlPatterns = "/profile"
)
public class ProfileServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
User user = new User();
user.setUserId(19384L);
user.setUsername("Coder314");
user.setFirstName("John");
user.setLastName("Smith"); Hashtable<String, Boolean> permissions = new Hashtable<>();
permissions.put("user", true);
permissions.put("moderator", true);
permissions.put("admin", false);
user.setPermissions(permissions); request.setAttribute("user", user);
request.getRequestDispatcher("/WEB-INF/jsp/view/profile.jsp")
.forward(request, response);
}
}

profile.jsp

<%--@elvariable id="user" type="com.wrox.User"--%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<title>User Profile</title>
</head>
<body>
User ID: ${user.userId}<br />
Username: ${user.username} (${user.username.length()} characters)<br />
Full Name: ${fn:escapeXml(user.lastName) += ', '
+= fn:escapeXml(user.firstName)}
<br /><br />
<b>Permissions (${fn:length(user.permissions)})</b><br />
User: ${user.permissions["user"]}<br />
Moderator: ${user.permissions["moderator"]}<br />
Administrator: ${user.permissions["admin"]}<br />
</body>
</html>

profile.jsp的<%--@elvariable id="user" type="com.wrox.User"--%>告诉IDE在本页的隐式作用域中有一个user变量,它的类型是com.wrox.User

下面的代码使用fn:escapeXml(...)函数对HTML字符进行转义,还使用了+=字符串连接操作符结合所有的字符串。

        Full Name: ${fn:escapeXml(user.lastName) += ', '
+= fn:escapeXml(user.firstName)}

1.2 使用EL的隐式变量

  • pageContext是PageContext类的一个实例,并且是唯一一个不是Map的隐式EL变量。
  • pageScope包含了所有绑定到PageContext的特性。
  • requestScope包含了所有绑定到ServletRequest的特性。
  • sessionScope包含了所有绑定到当前会话的特性。
  • paramparamValues。param包含了任何多值参数中的第一个值,而paramValues包含了所有参数的所有值。如果你知道请求参数只有一个值的话,param更易于使用。
  • headerheaderValues提供了对请求头的访问。header包含了多值头的第一个值,headerValues包含了所有参数的所有值。如果你知道header只有一个值的话,header更易于使用。
  • initParam包含了该应用程序中ServletContext实例的所有上下文初始化参数。
  • cookie包含了用户浏览器发送的请求中的所有cookie,如果存在名字相同的两个cookie,只显示按顺序出现的第一个。如果不遍历所有的cookie,在EL中就无法访问其他具有相同名字的重复cookie。
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%
application.setAttribute("appAttribute", "foo");
pageContext.setAttribute("pageAttribute", "bar");
session.setAttribute("sessionAttribute", "sand");
request.setAttribute("requestAttribute", "castle");
%>
<!DOCTYPE html>
<html>
<head>
<title>Information</title>
</head>
<body>
Remote Address: ${pageContext.request.remoteAddr}<br />
Request URL: ${pageContext.request.requestURL}<br />
Session ID: ${pageContext.request.session.id}<br />
Application Scope: ${applicationScope["appAttribute"]}<br />
Page Scope: ${pageScope["pageAttribute"]}<br />
Session Scope: ${sessionScope["sessionAttribute"]}<br />
Request Scope: ${requestScope["requestAttribute"]}<br />
User Parameter: ${param["user"]}<br />
Color Multi-Param: ${fn:join(paramValues["colors"], ', ')}<br />
Accept Header: ${header["Accept"]}<br />
Session ID Cookie Value: ${cookie["JSESSIONID"].value}<br />
</body>
</html>

上面的Session ID Cookie Value字段值为空,意味着会话才刚刚建立,浏览器尚未发送任何cookie,刷新页面后将会显示出会话ID Cookie值。

下面的JSP将演示EL表达式解析变量时不同作用域的优先级。

<%
pageContext.setAttribute("a", "page");
request.setAttribute("a", "request");
session.setAttribute("a", "session");
application.setAttribute("a", "application"); request.setAttribute("b", "request");
session.setAttribute("b", "session");
application.setAttribute("b", "application"); session.setAttribute("c", "session");
application.setAttribute("c", "application"); application.setAttribute("d", "application");
%>
<!DOCTYPE html>
<html>
<head>
<title>Scope Demonstration</title>
</head>
<body>
a = ${a}<br />
b = ${b}<br />
c = ${c}<br />
d = ${d}<br />
</body>
</html>

2.使用流API访问集合

流API的基础是所有Collection中存在的无参stream方法。

collections.jsp

<%@ page import="com.wrox.User" %>
<%@ page import="java.util.ArrayList" %>
<%
ArrayList<User> users = new ArrayList<>();
users.add(new User(19384L, "Coder314", "John", "Smith"));
users.add(new User(19383L, "geek12", "Joe", "Smith"));
users.add(new User(19382L, "jack123", "Jack", "Johnson"));
users.add(new User(19385L, "farmer-dude", "Adam", "Fisher"));
request.setAttribute("users", users);
%>
<!DOCTYPE html>
<html>
<head>
<title>Collections and Streams</title>
</head>
<body>
${users.stream()
.filter(u -> fn:contains(u.username, '1'))
.sorted((u1, u2) -> (x = u1.lastName.compareTo(u2.lastName);
x == 0 ? u1.firstName.compareTo(u2.firstName) : x))
.map(u -> {'username':u.username, 'first':u.firstName,
'last':u.lastName})
.toList()}
</body>
</html>

EL表达式对创建的用户列表进行过滤,只保留了用户名含有数字1的用户;先按姓后按名进行排序;在所有匹配的用户中选择用户名、名字和姓;然后立即执行返回一个List。

因为我们不鼓励在JSP中使用Java,所以也不鼓励将业务逻辑添加到表示层。

示例源码链接:https://pan.baidu.com/s/1-Z1hpN3YfVBlvqz-2B_OeA 密码:ppxz

Java EE之表达式语言EL(下)的更多相关文章

  1. Java EE之表达式语言EL(上)

    1.了解表达式语言 表达式语言(EL)用于在不使用脚本.声明或者表达式的情况下,在JSP页面中渲染数据. EL曾是JSTL 1.0规范(与JSP 1.2)中的一部分,并且只可以用作JSTL标签的特性. ...

  2. 表达式语言EL

    表达式语言EL 表达式语言 EL(Expression Language,表达式语言)主要是用在JSP页面中,用来辅助我们产生无脚本的JSP页面,此处的脚本指的是JSP中的Java代码. EL的语法是 ...

  3. 表达式语言EL简单学习

    Jsp2.0最重要的特性就是表达式语言EL.jsp用户可以用它来访问应用程序数据. EL表达式以${开头并以}结束. ${expresion}     ${x+y} 它也常用来连接两个表达式,取值将从 ...

  4. 关于JAVA EE项目在WEB-INF目录下的jsp页面如何访问WebRoot中的CSS和JS文件

    找了这么久资料,总算解决了 感谢博客园:http://www.cnblogs.com/xsht/p/5275081.html 感谢百度:http://zhidao.baidu.com/link?url ...

  5. 06.十分钟学会表达式语言EL

    一. 概念:MVC设计模式一个主要好处就是让jsp中的代码越来越来少,而且规定只能出现三种代码:接收属性,判断语句,迭代输出.但是,在开发中,jsp输出至少还是需要接受VO对象的,这时候为了避免导入V ...

  6. 【jsp】详解JSP表达式语言(EL)

    一.JSP EL语言定义 E L(Expression Language)  目的:为了使JSP写起来更加简单. 表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 ...

  7. Java EE Expression Language

    什么是EL? 形如这样(立即执行的): ${sessionScope.cart.total} 或者这样(延迟执行的): #{customer.name} 的表达式语言(Expression Langu ...

  8. Java EE JSP内置对象及表达式语言

    一.JSP内置对象 JSP根据Servlet API规范提供了一些内置对象,开发者不用事先声明就可使用标准变量来访问这些对象. JSP提供了9种内置对象: (一).request 简述: JSP编程中 ...

  9. JSP简明教程(四):EL表达式语言、JavaBean、Cookie、Session

    EL表达式语言 EL这是Expression Language.的目的是为了简化JSP句法.来看几个例子来清除. ${test} 它会被翻译成<%=test%> ${test.name} ...

随机推荐

  1. 使用Python 统计nginx日志前十ip访问量并以柱状图显示

    脚本内容: import matplotlib.pyplot as plt # nginx_file = '10.6.11.91_access.log-2018-12-27' ip = {} #筛选n ...

  2. whoami,who,w命令详解

    http://www.voidcn.com/blog/wszzdanm/article/p-6145895.html 命令功能:显示登录用户的信息 命令格式: 常用选项: 举例: w 显示已经登录的用 ...

  3. node上的__dirname和./的区别

    概要 Node.js 中,__dirname 总是指向被执行 js 文件的绝对路径,所以当你在 /d1/d2/myscript.js 文件中写了 __dirname, 它的值就是 /d1/d2 . 相 ...

  4. Python 标准库中的装饰器

    题目描述 1.简单举例 Python 标准库中的装饰器 2.说说你用过的 Python 标准库中的装饰器 1. 首先,我们比较熟悉,也是比较常用的 Python 标准库提供的装饰器有:property ...

  5. scrapy笔记集合

    细读http://scrapy-chs.readthedocs.io/zh_CN/latest/index.html 目录 Scrapy介绍 安装 基本命令 项目结构以及爬虫应用介绍 简单使用示例 选 ...

  6. 迎来OO的曙光,总结规格的意义——OO第四次博客总结

    一切都要结束了,砥砺前行~ 一.测试与正确性论证的效果差异 测试,顾名思义就是我们暴力用大量数据轰炸编写的程序的过程.日常的OO过程中,我们经常互相寻求“测试集”,正是因为测试使用特定数据对我们的功能 ...

  7. 20162314 《Program Design & Data Structures》Learning Summary Of The Seventh Week

    20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Seventh Wee ...

  8. spring冲刺第一天

    第一天总结 昨天我们开始了spring冲刺会议,我们进行了明确的分工,每个人都有自己的任务.我的目前任务是游戏地图的初步设计. 今天早上我们开了站立会议,算是正式开始了spring冲刺.我上网查找了一 ...

  9. Mininet-Wifi 多接入点(Access Point)实验

    实验简介  这个实验来自Mininet-Wifi用户手册.在本实验中,我们会创建一个有三个AP的线式拓扑,并有三个站点(station)与每个AP通过无线相连.将通过这个时间简单演示一些Mininet ...

  10. 第一次spring冲刺第9天

    明天是这个阶段的最后一天了,今天讨论关于容错的方面,例如输入空白或其他字符等方面会出现的问题 ,部分代码如下: public void checkout(int trueResult) { Strin ...