涉及到前端JSP的一些知识点,于是决定将JSP里面比较重要的两个重要的组成部分,这一次先总结梳理一下关于EL表达式的,以求未来能够直接查阅使用。
在我看来要理解EL需要理解四个东西以及一个思路:
- 作用域
- 11个隐含对象
- 运算符
函数
思路:EL的最大作用就是数据调控,简化流程。
下面一个个来说明这四个东西:
为此专门写了四个Test页面。
先将后台的代码贴上来,直接在现成的框架上搭建的测试类。
package com.cms.controller;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*@author:gang
*@version:
**/
@Controller
@RequestMapping("/test")
public class ELAction {
String mapString = "map";
String name="ant-black";
String id="11111";
int age = 22;
Date date = new Date();
static HashMap<String, String> elMap = new HashMap<String, String>();
static LinkedList<String> elList = new LinkedList<String>();
static String[][] arry={{"S1","S2","S3"},{"S4","S5","S6"}};
//跳转到首页,测试运算符
@RequestMapping("/EL")
public String modelEl(HttpServletRequest request,ModelMap map){
return "eltest";
}
//测试el的作用域
@RequestMapping("/elscope")
public String elscope(HttpServletRequest request,ModelMap map){
HttpSession session = request.getSession();
session.setAttribute("id", id);
request.setAttribute("name1", name);
return "elscope";
}
//测试el的隐含对象
@RequestMapping("/elobject")
public String elobject(HttpServletRequest request,ModelMap map){
HttpSession session = request.getSession();
session.setAttribute("map", map);
return "elobject";
}
//测试el的函数方法
@RequestMapping("/elfunction")
public String elfunction(HttpServletRequest request,ModelMap map){
HttpSession session = request.getSession();
request.setAttribute("name", name);
return "elfunction";
}
//以下均为EL的函数调用,均为Static静态函数
public static long localNowDate(){
Date date = new Date();
Long dateString = date.getYear()+date.getTime();
return dateString;
}
public static Map<String, String> elmap(){
elMap.put("001", "aaa");
elMap.put("002", "bbb");
elMap.put("003", "ccc");
return elMap;
}
public static LinkedList<String> ellist(){
elList.add("list1");
elList.add("list2");
elList.add("list3");
elList.add("list4");
return elList;
}
public static String[][] funcAlert(){
return arry;
}
public static String funcString(){
String string = "String success";
return string;
}
}
1.EL的运算符
简单介绍下EL的运算符
这个大家基本上都是知道的,EL的一个特点就是运算符能在其中使用,这可以极大的简化我们的代码流程。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ include file="/common/global.jsp" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset="utf-8">
<title>EL表达式使用案例</title>
<link rel="stylesheet" href="${ctxPath}/css/el.css">
</head>
<body>
<content>
<nav class="tabs">
<ul>
</ul>
</nav>
<ul class="features">
<li>
<div>
<table border=1>
<tr>
<td>算数运算符</td>
<td>结果</td>
</tr>
<tr>
<td>加法运算符\${1 + 1}</td>
<td>结果${1+1}</td>
</tr>
<tr>
<td>减法运算符\${1 - 1}</td>
<td>结果${1-1}</td>
</tr>
<tr>
<td>减法运算符\${(10 - 5)+1}</td>
<td>结果${(10 - 5)+1}</td>
</tr>
<tr>
<td>乘法运算符\${1 * 2}</td>
<td>结果${1 * 1}</td>
</tr>
<tr>
<td>除法运算符\${3 / 2}</td>
<td>结果${3 / 2}</td>
</tr>
<tr>
<td>求余运算符\${3 % 2}</td>
<td>结果${3 % 2}</td>
</tr>
</table>
<table border=1>
<tr>
<td>关系运算符</td>
<td>结果</td>
</tr>
<tr>
<td>等于运算符\${1 == 1}</td>
<td>结果${1==1}</td>
</tr>
<tr>
<td>不等于运算符\${1 != 1}</td>
<td>结果${1!=1}</td>
</tr>
<tr>
<td>小于运算符\${1 < 2}</td>
<td>结果${1 < 2}</td>
</tr>
<tr>
<td>大于运算符\${3 > 2}</td>
<td>结果${3 > 2}</td>
</tr>
<tr>
<td>小于等于运算符\${1 <= 2}</td>
<td>结果${1 <= 2}</td>
</tr>
<tr>
<td>大于等于运算符\${3 >= 2}</td>
<td>结果${3 >= 2}</td>
</tr>
</table>
<table border=1>
<tr>
<td>逻辑运算符</td>
<td>结果</td>
</tr>
<tr>
<td colspan="2">逻辑运算符&&</td>
</tr>
<tr>
<td>\${true && true}</td>
<td>结果${true && true}</td>
</tr>
<tr>
<td>\${true && false}</td>
<td>结果${true && false}</td>
</tr>
<tr>
<td>\${false && false}</td>
<td>结果${false && false}</td>
</tr>
<tr>
<td colspan="2">逻辑运算符||</td>
</tr>
<tr>
<td>\${true || true}</td>
<td>结果${true || true}</td>
</tr><tr>
<td>\${true || false}</td>
<td>结果${true || false}</td>
</tr><tr>
<td>\${false || false}</td>
<td>结果${false || false}</td>
</tr>
<tr>
<td colspan="2">逻辑运算符!</td>
</tr>
<tr>
<td>\${!true}</td>
<td>结果${!true}</td>
</tr><tr>
<td>\${!false}</td>
<td>结果${!false}</td>
</tr>
</table>
<table border=1>
<tr>
<td>条件运算符</td>
<td>结果</td>
</tr>
<tr>
<td>\${2>1?"Yes":"No"}</td>
<td>结果${2>1?"Yes":"No"}</td>
</tr>
<tr>
<td>\${2<1?"Yes":"No"}</td>
<td>结果${2<1?"Yes":"No"}</td>
</tr>
</table>
<table border=1>
<tr>
<td>验证运算符</td>
<td>结果</td>
</tr>
<tr>
<td>\${empty param.username}</td>
<td>结果${empty param.username}</td>
</tr>
<tr>
<td>\${empty param.password}</td>
<td>结果${empty param.password}</td>
</tr>
</table>
<table border=1>
<tr>
<td>括号运算符及运算符的优先级</td>
<td>结果</td>
</tr>
<tr>
<td>等于运算符\${1*2+1}</td>
<td>和数学运算一样,详见优先级表:结果${1*2+1}</td>
</tr>
</table>
</div>
</li>
</ul>
</content>
</body>
</html>
结果是这样的:
在于优先级,这个就不需要多说了。
2.EL的作用域
EL的作用域和Jsp是通用的,包括四个:
属性范围(jstl名称) | EL中的名称 | 解释 |
---|---|---|
Page | PageScope | 当前,可以理解为类似于Java中this的存在 |
Request | RequestScope | 请求 |
Session | SessionScope | 一次回话,通常不做其他的设置的话,一次回话就是一次登录或者说打开浏览器的过程 |
Application | ApplicationScope | 全局,意味着一个应用,项目 |
我们也可以指定要取出哪一个范围的变量:
范例 | 说明 |
---|---|
${pageScope.username} | 取出Page范围的username变量 |
${requestScope.username} | 取出Request范围的username变量 |
${sessionScope.username} | 取出Session范围的username变量 |
${applicationScope.username} | 取出Application范围的username变量 |
<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ include file="/common/global.jsp" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset="utf-8">
<title>EL表达式使用案例</title>
<link rel="stylesheet" href="${ctxPath}/css/el.css">
<%
//application范围设置属性name,值为application_name
application.setAttribute("name","application_name");
//session范围设置属性name,值为session_name
request.getSession().setAttribute("name", "session_name");
String sessionname = (String) request.getSession().getAttribute("id");
String sessionname2 = (String) request.getSession().getAttribute("name");
application.setAttribute("sessionname", sessionname);
application.setAttribute("sessionname2", sessionname2);
//request范围设置属性name,值为request_name
request.setAttribute("name","request_name");
//page范围设置属性name,值为page_name
pageContext.setAttribute("name","page_name");
%>
</head>
<body>
<content>
<ul class="features">
<li>
<div>
<p>${sessionScope.id }</p>
<p>页面内设置参数</p>
<table border=1>
<tr>
<%--获取page范围内的name属性--%>
<td>\${pageScope.name}---page范围内的那么属性的值为:</td>
<td>${pageScope.name}</td>
</tr>
<tr>
<%--获取request范围内的name的属性--%>
<td> \${requestScope.name}---request范围内的那么属性的值为:</td>
<td> ${requestScope.name}</td>
</tr>
<tr>
<%--获取session范围内的name的属性--%>
<td> \${sessionScope.id}---session范围内的那么属性的值为:</td>
<td>${sessionScope.id}</td>
</tr>
<tr>
<%--获取application范围内的name属性--%>
<td> \${applicationScope.name}---${applicationScope.name}---application范围内的那么属性的值为:</td>
<td> ${applicationScope.name}</td>
</tr>
</table>
<p>后台requestname1在不同作用域里面的显示</p>
<%--后台requestname1在不同作用域里面的显示--%>
<table border=1>
<tr>
<%--获取page范围内的name属性--%>
<td>\${pageScope.name1}---page范围内的那么属性的值为:</td>
<td>${pageScope.name1}</td>
</tr>
<tr>
<%--获取request范围内的name的属性--%>
<td> \${requestScope.name1}---request范围内的那么属性的值为:</td>
<td> ${requestScope.name1}</td>
</tr>
<tr>
<%--获取session范围内的name的属性--%>
<td>\${sessionScope.name1}---session范围内的那么属性的值为:</td>
<td>${sessionScope.name1}</td>
</tr>
<tr>
<%--获取application范围内的name属性--%>
<td> \${applicationScope.name1}---application范围内的那么属性的值为:</td>
<td> ${applicationScope.name1}</td>
</tr>
</table>
<p>后台sessionid在不同作用域里面的显示</p>
<%--后台sessionid在不同作用域里面的显示--%>
<table border=1>
<tr>
<%--获取page范围内的id属性--%>
<td>\${pageScope.id}---page范围内的那么属性的值为:</td>
<td>${pageScope.id}</td>
</tr>
<tr>
<%--获取request范围内的id的属性--%>
<td>\${applicationScope.sessionname}---request范围内的那么属性的值为:</td>
<td> ${applicationScope.sessionname}</td>
</tr>
<tr>
<%--获取session范围内的id的属性--%>
<td> session范围内的那么属性的值为:\${sessionScope.id}---\${!empty sessionScope.id}</td>
<td>${sessionScope.id}---${!empty sessionScope.id}</td>
</tr>
<tr>
<%--获取application范围内的id属性--%>
<td> \${applicationScope.sessionname2}application范围内的那么属性的值为:</td>
<td> ${applicationScope.sessionname2}</td>
</tr>
</table>
</div>
</li>
</ul>
</content>
</body>
</html>
这里我出现了一个问题,且一直无法解决。。。。
sessionScope无论如何也取不出我的数据,但是我使用:
String sessionname = (String) request.getSession().getAttribute("id");
String sessionname2 = (String) request.getSession().getAttribute("name");
application.setAttribute("sessionname", sessionname);
application.setAttribute("sessionname2", sessionname2);
这种情况下我是可以取出session的数据的,对此我一直很疑惑
欢迎大家帮我解答或讨论,非常感谢!
3.EL的11个隐藏对象
同样的,贴上代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ include file="/common/global.jsp" %>
<%
Cookie cookie=new Cookie("name","ant-black");
response.addCookie(cookie);
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset="utf-8">
<title>EL表达式使用案例</title>
<link rel="stylesheet" href="${ctxPath}/css/el.css">
</head>
<body>
<content>
<nav class="tabs">
<ul>
</ul>
</nav>
<ul class="features">
<li>
<div>
<h1>11大隐藏对象</h1>
<p>pageContex内置对象
</p>
<table border=1>
<tr>
<td>取得请求的参数的字符串\${pageContext.request.queryString}</td>
<td>${pageContext.request.queryString}</td>
</tr>
<tr>
<td>取得请求URL\${pageContext.request.requestURL}</td>
<td> ${pageContext.request.requestURL}</td>
</tr>
<tr>
<td>取得web应用名称\${pageContext.request.contextPath}</td>
<td>${pageContext.request.contextPath}</td>
</tr>
<tr>
<td>取得HTTP请求方式(POST/GET)\${pageContext.request.method}</td>
<td>${pageContext.request.method}</td>
</tr>
<tr>
<td>取得使用的协议\${pageContext.request.protocol}</td>
<td>${pageContext.request.protocol}</td>
</tr><tr>
<td>取得用户IP地址\${pageContext.request.remoteAddr}</td>
<td>${pageContext.request.remoteAddr}</td>
</tr><tr>
<td>取得session的id\${pageContext.session.id}</td>
<td>${pageContext.session.id}</td>
</tr>
</table>
<!-- header -->
<h2> header</h2>
获得host\${header["host"]}------${header["host"]}<br />
获得头文件信息\${header["user-agent"]}--------${header["user-agent"]}<br />
<h2> cookie</h2>
<!-- cookie
-->
获取cookie设置的值 \${cookie.name.value}-------${cookie.name.value}
</div>
</li>
</ul>
</content>
</body>
</html>
这个就比较简单了,通常就是使用隐藏对象调用方法即可,一般返回的也是各种类型的数据。
具体有哪些方法就没有整理了,具体情况具体查询。
值得一提的是EL的fn函数
函数 | 描述 |
---|---|
fn:contains(string, substring) | 如果参数string中包含参数substring,返回true |
fn:containsIgnoreCase(string, substring) | 如果参数string中包含参数substring(忽略大小写),返回true |
fn:endsWith(string, suffix) | 如果参数 string 以参数suffix结尾,返回true |
fn:escapeXml(string) | 将有特殊意义的XML (和HTML)转换为对应的XML character entity code,并返回 |
fn:indexOf(string, substring) | 返回参数substring在参数string中第一次出现的位置 |
fn:join(array, separator) | 将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。 |
fn:length(item) | 返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。如果是String类型,返回值是String中的字符数。 |
fn:replace(string, before, after) | 返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果 |
fn:split(string, separator) | 返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素 |
fn:startsWith(string, prefix) | 如果参数string以参数prefix开头,返回true |
fn:substring(string, begin, end) | 返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符 |
fn:substringAfter(string, substring) | 返回参数substring在参数string中后面的那一部分字符串 |
fn:substringBefore(string, substring) | 返回参数substring在参数string中前面的那一部分字符串 |
fn:toLowerCase(string) | 将参数string所有的字符变为小写,并将其返回 |
fn:toUpperCase(string) | 将参数string所有的字符变为大写,并将其返回 |
fn:trim(string) | 去除参数string 首尾的空格,并将其返回 |
4.EL的自定义方法
这可能是EL中最不容易理解的一个部分
主要就几个部分:
- 静态方法
- TLD文件
- web.xml配置
- 前端导入使用
1.静态文件
public static long localNowDate(){
Date date = new Date();
Long dateString = date.getYear()+date.getTime();
return dateString;
}
public static Map<String, String> elmap(){
elMap.put("001", "aaa");
elMap.put("002", "bbb");
elMap.put("003", "ccc");
return elMap;
}
public static LinkedList<String> ellist(){
elList.add("list1");
elList.add("list2");
elList.add("list3");
elList.add("list4");
return elList;
}
public static String[][] funcAlert(){
return arry;
}
public static String funcString(){
String string = "String success";
return string;
}
2.elfunction.tld
这个文件可以放在任何能引用到的地方,我是放在WEB-INF中
<?xml version="1.0" encoding="utf-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>elfunctiontag</short-name>
<uri>elfunctiontag</uri>
<function>
<description>show local now dateTime</description>
<name>localNowDate</name>
<function-class>com.cms.controller.ELAction</function-class>
<function-signature>java.util.Date localNowDate()</function-signature>
</function>
<function>
<description>elmap</description>
<name>elmap</name>
<function-class>com.cms.controller.ELAction</function-class>
<function-signature>java.util.HashMap elmap()</function-signature>
</function>
<function>
<description>ellist</description>
<name>ellist</name>
<function-class>com.cms.controller.ELAction</function-class>
<function-signature>java.util.LinkedList ellist()</function-signature>
</function>
<function>
<description>funcAlert</description>
<name>funcAlert</name>
<function-class>com.cms.controller.ELAction</function-class>
<function-signature>java.lang.String funcAlert()</function-signature>
</function>
<function>
<description>funcString</description>
<name>funcString</name>
<function-class>com.cms.controller.ELAction</function-class>
<function-signature>java.lang.String funcString()</function-signature>
</function>
</taglib>
3.web.xml
注意,,某个版本之后需要加上< jsp-config>,之前可以直接使用< taglib>
<jsp-config>
<taglib>
<taglib-uri>/elfunctiontag</taglib-uri>
<taglib-location>/WEB-INF/elfunction.tld</taglib-location>
</taglib>
</jsp-config>
4.前台页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="eltag" uri="/elfunctiontag"%>
<%@ page session="false"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ include file="/common/global.jsp" %>
<%
Cookie cookie=new Cookie("name","ant-black");
response.addCookie(cookie);
HashMap hashMap = new HashMap();
hashMap.put("aaa", "111");
LinkedList linkList = new LinkedList();
linkList.add("11111111111");
application.setAttribute("list",linkList);
application.setAttribute("hashmap",hashMap);
String sessionname = (String) request.getSession().getAttribute("id");
String sessionname2 = (String) request.getSession().getAttribute("name");
application.setAttribute("sessionname", sessionname);
application.setAttribute("sessionname2", sessionname2);
//request范围设置属性name,值为request_name
request.setAttribute("name","request_name");
//page范围设置属性name,值为page_name
pageContext.setAttribute("name","page_name");
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset="utf-8">
<title>EL表达式使用案例</title>
<link rel="stylesheet" href="${ctxPath}/css/el.css">
</head>
<body>
<content>
<nav class="tabs">
<ul>
</ul>
</nav>
<ul class="features">
<li>
<div>
<h1>function</h1>
<table border=1>
<tr>
<td>取得字符串\${eltag.funcString}</td>
<td>${eltag:funcString()}</td>
</tr>
<td>取得时间\${eltag:funcString()}</td>
<td> ${eltag:localNowDate()}</td>
</tr>
<tr>
<td>取得map\${eltag:funcString()}</td>
<td>${eltag:elmap()}</td>
</tr>
<tr>
<td>取得list\${eltag:ellist()}</td>
<td>${eltag:ellist()}</td>
</tr>
<tr>
<td>取得funcAlert\${eltag:funcAlert()}</td>
<td>${eltag:funcAlert()}</td>
</tr>
</table>
\${applicationScope.hashmap.aaa}-----${applicationScope.hashmap.aaa}<BR>
\${applicationScope.list[0]}-----${applicationScope.list[0]}
</div>
</li>
<funcStringontent>
</body>
</html>
观察代码可以发现map,list,array均是以字符串的方式打印,数组打印的是一个地址引用
我一直测试能否将他们作为对象使用,但是一直不成功,如果知道方法烦请告知,感谢
其中还有对于list,map集合对象的取值方式,注意map是key值(和数组一样),list是取索引
\${applicationScope.hashmap.aaa}-----${applicationScope.hashmap.aaa}<BR>
\${applicationScope.list[0]}-----${applicationScope.list[0]}
5.总结
EL是一个辅助性语言,能极大的简化JSP的书写
写了这么多突然发现FreeMarker似乎用不到他们~~~~