javaweb之jsp详解三-EL表达式和JSTL略解

表达式语言(Expression Language)简称EL,它是JSP2.0中引入的一个新内容。通过EL可以简化在JSP开发中对对象的引用,从而规范页面代码,增加程序的可读性及可维护性。EL为不熟悉Java语言页面开发的人员提供了一个开发Java Web应用的新途径。下面对EL的语法、运算符及隐含对象进行简单介绍(EL就不详解介绍了,这里主要介绍一些常用的,有需要的自己了解一下)。

EL简介

EL没出现之前,开发Java Web应用程序时,经常需要将大量的Java代码片段嵌入到JSP页面中,这会使页面开起来很乱,如下例子:

<%if(session.getAttribute(“username”)!= null){ 

       out.println(session.getAttribute(“username”).toString()); 

}%>  

经常写这种痛苦的代码杀了我们算了,所以EL应运而生
以上代码只需下面的简单代码即可:

${username}

通过上面的例子我们可以知道,EL表达式的语法非常简单,它以”${”开头,以”}”结束,中间为合法的表达式,具体的语法格式为:

${expression}

expression用于指定要输出的内容,可以使字符串,也可以是由EL运算符组成的表达式。

EL的特点:

  • EL表达式不能出现在Java代码块、表达式块等JSP动态代码部分
  • EL只能从四大域属性空间中获取数据(pageContext、request、session、application)
  • EL不会抛出空指针异常,只会不显示
  • EL不会抛出数组越界异常,只会不显示
  • EL不具有对字符串进行处理的能力(可以使用JSTL的EL或者自定义EL函数)
  • EL中会自动进行类型转换。如果想通过EL输入两个字符串型数值的和,可以直接通过”+”号进行连接,如${num1+num2};
  • EL不仅可以访问一般变量,还可以访问JavaBean中的属性以及嵌套属性和集合对象;
  • 在EL中可以获得命名空间(PageContext对象,它是页面中所有其他内置对象的最大范围的集成对象,通过它可以访问其他内置对象);
  • 在使用EL进行除法运算时,如果除数为0,则返回无穷大Infinity,而不是错误;
  • EL可以与JSTL结合使用,也可以与JavaScript语句结合使用;
  • 扩展函数可以与Java类的静态方法进行映射。

EL的常用方法

EL的算数运算符

运算符 功能 示例 结果
+ ${1+1} 2
${1-1} 0
* ${2*2} 4
/或div 2/0或{2 div 0} Infinity
%或 mod 求余 {3%0}或{3 mod0} 异常:java.lang.ArithmeticException:/by zero

EL关系运算符

关系运算符 说明 范例 结果
== 或 eq 等于 ${5==5}或${5eq5} true
!= 或 ne 不等于 ${5!=5}或${5ne5} false
< 或 lt 小于 ${3<5}或${3lt5} true
> 或 gt 大于 ${3>5}或{3gt5} false
<= 或 le 小于等于 ${3<=5}或${3le5} true
>= 或 ge 大于等于 ${3>=5}或${3ge5} false

El逻辑运算符

逻辑运算符 范例 结果
&&或and 交集${A && B}或${A and B} true/false
或or|并集${A ¦ ¦ B}或${A or B}|true/false
!或not 非${! A }或${not A} true/false

Empty 运算符和条件运算符

1、在EL中判断对象是否为空

    ${empty expression}

2、条件运算符

${ A ? B : C}

EL的11个隐式对象

隐含对象 类型 说明
PageContext javax.servlet.ServletContext 表示此JSP的PageContext
PageScope java.util.Map 取得Page范围的属性名称所对应的值
RequestScope java.util.Map 取得Request范围的属性名称所对应的值
sessionScope java.util.Map 取得Session范围的属性名称所对应的值
applicationScope java.util.Map 取得Application范围的属性名称所对应的值
param java.util.Map 如同ServletRequest.getParameter(String name)。回传String类型的值
paramValues java.util.Map 如同ServletRequest.getParameterValues(String name)。回传String[]类型的值
header java.util.Map 如同ServletRequest.getHeader(String name)。回传String类型的值
headerValues java.util.Map 如同ServletRequest.getHeaders(String name)。回传String[]类型的值
cookie java.util.Map 如同HttpServletRequest.getCookies()
initParam java.util.Map 如同ServletContext.getInitParameter(String name)。回传String类型的值

EL获取属性

1、普通获取

从四大作用域中直接获取xxxxx属性,会从最小的域查找到最大的域
${xxxxx}

2、从某个域获取属性name

${applicationScope.name }

3、pageContext

在EL中直接${pageContext.request}即可获取request对象,其底层调用的是pageContext.getRequest()方法。同理,也可以通过类似方法获取其他对象

其中最常用的:${pageContext.request.contextPath },代表web应用下的根

4、${param.name }

其底层实际调用request.getParameter()

5、paramValues

${paramValues.hobby[0] }
${paramValues.hobby[1] }

6、initParam

获取初始化参数,其底层调用的是ServletContext.getInitParameter()

7、访问bean属性

${student.name} 
student是bean,name是其属性

8、访问数组和List

${students[1].name}  students是数组或者List

9、访问Map

${map.name }  map是Map,name是键,获取其值

自定义EL函数

因为EL本身不具有处理字符串能力,所以可以自定义EL函数

  • 定义函数(新建MyEL.java类)
  • 注册:先找到jsp2-example-taglib.tld,将头部以及注册函数复制到自己创建的.tld文件中(.tld放在WEB-INF下)
  • 在index.jsp中使用,使用时需要<%@ taglib uri=”http://tomcat.apache.org/jsp2-example-taglib” prefix=”MyEL” %>
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.5//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" > 
<web-app>
 ... 
</web-app>

描述符2.4或者更新的版本,isELIgnored默认值为false,而2.3或者 更早的版本isELIgnored默认值为true。就导致了出现EL表达式无效的情况(浪费我很长时间,一直在找我的配置问题)。
解决方法1、: 在jsp page指令中共添加属性isELIgnored=”false”
解决方法2、删除web-app之上的头部代码,然后
在web.xml中年添加以下代码

<jsp-config>
     <jsp-property-group> 
        <url-pattern>*.jsp</url-pattern> 
        <el-ignored>false</el-ignored> 
    </jsp-property-group> 
<taglib>
            <taglib-uri>http://testcomp.com/testcomp/core</taglib-uri>
            <taglib-location>/WEB-INF/tlds/MyEL.tld</taglib-location>
        </taglib>
</jsp-config>

此时将el.jsp中的

<%@ taglib uri="http://testcomp.com/testcomp/core" prefix="MyEL" %>

换为

<%@ taglib uri="http://testcomp.com/testcomp/core" prefix="MyEL" %>

即可,这样写有个好处,就是当tld的路径发生改变的时候只需修改web.xml中的路径,而不必每个用到的jsp文件

定义类和处理函数

注意:方法必须是静态的

/**
 * 
 */
package el;

/**
 * @author Administrator
 *
 */
public class MyEL {

    // 字符串小写变大写
    public static String lowerToUpper(String str) {
    return str.toUpperCase();
    }

}

定义tld文件

在WEB-INF文件下新建一个tld文件,文件头从tomcat的webapps\examples\WEB-INF\jsp2目录的jsp2-example-taglib.tld文件中考过来
如下:

<?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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>这是我自定义的EL</description>
    <tlib-version>1.0</tlib-version>
    <short-name>MyEL</short-name><!-- 标签库名称,一般定义成和文件名一样 -->
    <!-- <uri>http://tomcat.apache.org/jsp2-example-taglib</uri> -->
    <!-- 注册函数 -->
    <function>
        <name>MyLowerToUpper</name>
        <function-class>el.MyEL</function-class><!-- 方法的类 -->
        <function-signature>java.lang.String lowerToUpper(java.lang.String )</function-signature>
    </function>

</taglib>

在el.jsp文件中通过taglib指令引入

<%@ page language="java" import="java.util.*" isELIgnored="false"  pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib uri="/WEB-INF/tlds/MyEL.tld" prefix="MyEL" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>EL表达式测试页面</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
   <%
        String name="xlj";
        pageContext.setAttribute("name", name);
    %>
  <body>
    ${MyEL:MyLowerToUpper(name)} <br>
  </body>
</html>

其中isELIgnored=”false” 最好写上,省的遇到莫名其妙的版本问题,prefix是标签的缩略,可以自定义

《javaweb之jsp详解三-EL表达式和JSTL略解》

JSTL

引入方式

步骤1:在pom.xml中添加以下配置

方式1:1.2及以上版本

      <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

方式2:1.2以下的版本需要

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.1.2</version>
</dependency>
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

步骤2:在jsp头部引入

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

步骤三:在jsp中使用

<c:if test="${5>3}" var="string">
   c:if测试
</c:if>

关于JSTL的具体使用方法参考学习菜鸟教程JSTL

参考

Java Web—-EL(表达式语言)详解

JSP中EL表达式的用法详解(必看篇)

EL表达式详解

JavaWeb学习篇之—-自定义标签&&JSTL标签库详解

点赞

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注