EL以及JSTL

EL工具包介绍

由Java技术开发一个jar包

作用:降低JSP文件开发时Java命令开发强度

Tomcat服务器本身自带了EL工具包(Tomcat安装地址/lib/el-api.jar

JSP相关知识本文中有JSP规范的相关介绍

EL表达式

 1.命令格式:${作用域对象别名.共享数据}
 2.命令作用:
       1)EL表达式是EL工具包提供一种特殊命令格式【表达式命令格式】
       2)EL表达式在JSP文件上使用
       3)执行时从指定的【作用域对象】中读取指定【共享数据】的内容并自动的写入到响应体

EL表达式作用域对象别名

1.JSP文件可以使用的作用域对象

    1) ServletContext     application:  全局作用域对象

    2) HttpSession        session:      会话作用域对象

    3) HttpServletRequest request:      请求作用域对象

    4) PageContext        pageContext: 当前页作用域对象

    这是JSP文件独有的作用域对象。Servlet中不存在

    在当前页作用域对象存放的共享数据仅能在当前JSP文件中使用,不能共享给其他Servlet或则其他JSP文件

真实开发过程,主要用于JSTL标签与JSP文件之间数据共享数据

    JSTL------->pageContext---->JSP

2.EL表达式提供作用域对象别名

          JSP                       EL表达式

      application               ${applicationScope.共享数据名}

      session                   ${sessionScope.共享数据名}

      request                   ${requestScope.共享数据名}

      pageContext               ${pageScope.共享数据名}

下面用代码演示一下分别使用java代码和EL表达式在JSP中实现共享数据的读取

Servlet

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //分别将共享数据添加到作用域对象
        //全局作用域对象
        ServletContext application=request.getServletContext();
        //会话作用域对象
        HttpSession session=request.getSession();

        application.setAttribute("sId",10);
        session.setAttribute("sName","mike");
        request.setAttribute("home","北京");
        //通过请求转发的方式调用index_1.jsp,由index_1.jsp负责将作用域对象共享数据读取并写入响应体中
        request.getRequestDispatcher("/index_1.jsp").forward(request,response);
    }
}

使用Java代码读取共享数据

<%
    //读取全局作用域对象中的共享数据
    Integer sId=(Integer) application.getAttribute("sId");
    //读取会话作用域对象中的共享数据
    String sName=(String)session.getAttribute("sName");
    //读取请求作用域对象中的共享数据
    String home=(String)request.getAttribute("home");
%>
sId:<%=sId%><br/>
sName:<%=sName%><br/>
home:<%=home%><br/>

使用EL表达式

学员Id:${applicationScope.sId}<br/>
学员姓名:${sessionScope.sName}<br/>
学员地址:${requestScope.home}<br/>

很明显EL表达式简化了在JSP文件中读取共享数据的步骤

EL表达式将引用对象属性写入响应体中

1.命令格式: ${作用域对象别名.共享数据名.属性名}
2.命令作用: 从作用域对象读取指定共享数据关联的引用对象的属性值。并自动将属性的结果写入到响应体
3.属性名: 一定要去引用类型属性名完全一致(大小写)
4.EL表达式没有提供遍历集合方法,因此无法从作用域对象读取集合内容输出

首先创建一个Student类

public class Student {
    private Integer sId;
    private String sName;

    public Student() {
    }

    public Student(Integer sId, String sName) {
        this.sId = sId;
        this.sName = sName;
    }

    public Integer getsId() {
        return sId;
    }

    public void setsId(Integer sId) {
        this.sId = sId;
    }

    public String getsName() {
        return sName;
    }

    public void setsName(String sName) {
        this.sName = sName;
    }
}

创建Servlet

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建一个引用类型实例对象
        Student student=new Student(10,"mike");
        //将引用类型对象存入请求作用域对象
        request.setAttribute("student",student);
        //请求转发,向Tomcat申请调用index_1.jsp
        request.getRequestDispatcher("/index_1.jsp").forward(request,response);
    }
}

index_1.jsp

学生编号:${requestScope.student.sId}<br/>
学生姓名:${requestScope.student.sName}<br/>

EL表达式简化版

1.命令格式: ${共享数据名}

2.命令作用: EL表达式允许开发人员开发时省略作用域对象别名

3.工作原理:

   EL表达式简化版由于没有指定作用域对象,所以在执行时采用【猜】算法

  首先到【pageContext】定位共享数据,如果存在直接读取输出并结束执行

  如果在【pageContext】没有定位成功,到【request】定位共享数据,如果存在直接读取输出并结束执行

  如果在【request】没有定位成功,到【session】定位共享数据,如果存在直接读取输出并结束执行

  如果在【session】没有定位成功,到【application】定位共享数据,如果存在直接读取输出并结束执行

  如果在【application】没有定位成功,返回null

  pageContext--->request--->session--->application

4.存在隐患:

             容易降低程序执行速度【南辕北辙】

             容易导致数据定位错误

5.应用场景:

              设计目的,就是简化从pageContext读取共享数据并输出难度

               简化版设计之初就是为了从当前页作用域对象读取数据并输出。所以从request,session,application读取数据并输出时应                 该避免使用简化版

6.EL表达式简化版尽管存在很多隐患,但是在实际开发过程中,开发人员为了节省时间,一般都使用

  简化版,拒绝使用标准版

Servlet

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //向当前用户session添加一个共享数据
        HttpSession session=request.getSession();
        session.setAttribute("key","hehe");

        //向当前请求作用域对象中添加一个共享数据
        request.setAttribute("key","haha");

        //通过请求转发方式,申请调用index_1.jsp
        request.getRequestDispatcher("/index_1.jsp").forward(request,response);
    }
}

index_1.jsp

标准版EL表达式输出session中的key值:${sessionScope.key}<br/>
简化版EL表达式输出session中的key值:${key}

EL表达式支持运算表达式

1.前提:  在JSP文件有时需要将读取共享数据进行一番运算之后,将运算结果写入到响应体

2.运算表达式:

   1) 数学运算

   2) 关系运算:  >    >=   ==    <   <=  !=    gt   ge    eq   lt  le   !=

   3)逻辑运算:  &&   ||    !

演示数学运算

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("key1","100");
        request.setAttribute("key2",200);
        //通过请求转发的方式调用index_1.jsp 并将结果写入到响应体中
        request.getRequestDispatcher("index_1.jsp").forward(request,response);
    }
}
<!--将作用域对象中共享数据读取出来相加,将相加的结果写入到响应体中-->
<%
    String num1=(String)request.getAttribute("key1");
    Integer num2=(Integer)request.getAttribute("key2");
    int sum=Integer.valueOf(num1)+num2;
%>
传统的java命令计算后的结果:<%=sum%>
<hr/>
EL表达式计算后的结果:${requestScope.key1+requestScope.key2}

演示关系运算

public class TwoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("age",25);
        request.getRequestDispatcher("index_2.jsp").forward(request,response);
    }
}
<!--传统Java命令实现关系运算的输出-->
<%
    Integer age=(Integer)request.getAttribute("age");
%>
<%
    if (age>18){
%>
欢迎光临<br/>
<%
    }else {
%>
谢绝入内<br/>
<%
    }
%>
EL表达式输出关系运算
${age>18?"欢迎光临":"谢绝入内"}

EL表达式提供的内置对象

术语

                  定义

               param

将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式 ${param . name}相当于 request.getParameter (name)。

              paramValues

将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 ${paramvalues. name} 相当于 request.getParamterValues(name)。

             header

将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 ${header. name} 相当于 request.getHeader(name)。

            headerValues

将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式 ${headerValues. name} 相当于 request.getHeaderValues(name)。

           cookie

将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 ${cookie. name .value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues. name} 表达式

           initParam

将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。

param

相当于java代码中的request.getParameter();

1.命令格式: ${param.请求参数名}

2.命令作用: 通过请求对象读取当前请求包中请求参数内容,并将请求参数内容写入到响应体

3.代替命令:  index.jsp

    发送请求:  Http://localhost:8080/myWeb/index_1.jsp?userName=mike&password=123

        <%

        String userName =   request.getParameter("userName");

        String password =   request.getParameter("password");

      %>

     <%=userName%>

     <%=password%>

paramValues

相当于java代码中的request.getParameterValues();

1.命令格式:${paramValues.请求参数名[下标]}

2.命令作用:

    如果浏览器发送的请求参数是[一个请求参数关联多个值]

    此时可以通过paramValues读取请求参数下指定位置的值并写入到响应体

3.代替命令: http://localhost:8080/myWeb/index_2.jsp?pageNo=1&pageNo=2&pageNo=3

    此时pageNo请求参数在请求包以数组形式存在

    pageNo:[1,2,3]

    <%

        String  array[]= request.getParameterValues("pageNo");

    %>

    第一个值:<%=array[0]%>

    第二个值:<%=array[1]%>

pageContext

对应的完整的java类名:javax.servlet.jsp.PageContext

这个内置对象在EL表达式中对应的隐含对象是:PageContext

使用EL表达式从pageContext范围中取数据的时候使用EL表达式中的内置对象pageScope

如果想调用pageContext内置对象的方法,需要使用EL表达式的内置对象pageContext

举例:使用EL表达式获取base路径

使用java代码获取base路径
<%
    String path=request.getScheme()+"://"+request.getServerName()+request.getServerPort()+"/"+request.getContextPath();
%>
<%=path%>
<br/>
使用EL表达式内置对象PageContext
${pageContext.request.scheme}://${pageContext.request.serverName}${pageContext.request.serverPort}/${pageContext.request.contextPath}
<br/>

使用EL表达式从Map集合中读取数据

<%
        Map<String,Emp> empMap=new HashMap<>();
        empMap.put("e1",e1);
        empMap.put("e2",e2);
        request.setAttribute("empMap",empMap);
 %>
    员工1:${empMap.get("e1").ename}
    员工1编号:${empMap.get("e1").eno}
    员工2:${empMap.get("e1").ename}
    员工2编号:${empMap.get("e1").eno}

使用EL表达式从List集合中读取数据

<%
    List<Emp> empList=new ArrayList<Emp>();
    empList.add(e1);
    empList.add(e2);
    request.setAttribute("empList",empList);
%>
${empList[0]}
${empList[1]}
${empList[0].ename}
${empList[1].ename}

EL表达式的专有异常

javax.el.PropertyNotFoundException:类型【xxxx】不存在【属性名】既在某个类中没有找到对应的属性

JSTL

(JSP Standard Tag Libary)jsp标准的标签库(掌握核心标签 c标签)

使用标签代替java代码,标准是sun制定的,Apache实现的(sun收录)

使用JSTL的步骤:

        *导入jar包 jstl.jar standard.jar

        *在需要使用标签额jsp页面上使用taglib指令引入标签库

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

        *在需要使用标签的位置直接使用标签即可

解释标签

<tag>
   <description></description>                                                         标签的描述
   <name>if</name>                                                                     标签的名字
   <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class>                标签对应的需要执行的类
   <body-content>JSP</body-content>                                                    标签体中的内容类型
   <attribute>                                                                         标签中可以出现的属性
       <description></description>                                                     对属性的描述
       <name>test</name>                                                               属性的名字
       <required>true</required>                                                       该属性是否是必须的 true是必须的
       <rtexprvalue>true</rtexprvalue>                                                 该属性是否可以接收EL表达式  true表示支持接收EL表达式
	<type>boolean</type>                                                                该属性的数据类型
   </attribute>
   <attribute>
       <description></description>
       <name>var</name>
       <required>false</required>
       <rtexprvalue>false</rtexprvalue>
   </attribute>
   <attribute>
       <description></description>
       <name>scope</name>
       <required>false</required>
       <rtexprvalue>false</rtexprvalue>
   </attribute>
 </tag>

常用的标签

<%--模拟if...else--%>
<c:choose>
    <c:when test="${param.age<5}">
        婴幼儿
    </c:when>
    <c:when test="${param.age<18}">
        少年
    </c:when>
    <c:when test="${param.age<35}">
        青年
    </c:when>
    <c:otherwise>
        老年
    </c:otherwise>
</c:choose>
<hr/>
<%--循环foreach--%>
<c:forEach begin="1" end="10" step="1" var="i">
    ${i}
</c:forEach>
<br/>
<%--java代码--%>
<%
    for(int i=1;i<=10;i++){
    pageContext.setAttribute("i",i);
%>
${i}
<%
}
%>
<hr/>
<%--循环获取List集合--%>
<%
    List<Emp> empList=new ArrayList<Emp>();
    Emp e1=new Emp(110,"张三");
    Emp e2=new Emp(111,"李四");
    Emp e3=new Emp(112,"王五");
    empList.add(e1);
    empList.add(e2);
    empList.add(e3);
    pageContext.setAttribute("empList",empList);
%>
<c:forEach items="${empList}" var="emp" varStatus="empStatus">
    ${empStatus.count}、${emp.eno}、${emp.ename}<br/>
</c:forEach>
<br/>
<%--使用java代码--%>
<%
    for(Emp e:empList){
        pageContext.setAttribute("e",empList);
%>
<%=e.getEno()%>、<%=e.getEname()%><br/>
<%
    }
%>
<hr/>
<%--可以切割字符串--%>
<%--127.0.0.1,192.168.1.100,192.168.1.3,192.168.8.4--%>
<c:forTokens items="${initParam.ips}" delims="," var="ip">
    ${ip}<br/>
</c:forTokens>

函数

1、函数是对EL表达式的补充,函数是属于JSTL的一部分,对应的配置文件是:stander.jar中的fn.tld文件

2、函数也是联合EL表达式也是代替jsp中的Java代码的

3、函数分:内置函数、自定义函数

4、内置函数的使用步骤

    *导入jar包(jstl.jar、standard.jar)

    *使用taglab指令导入函数库

    *在需要使用函数的位置使用即可

5、函数详解

<function>                                                                                          函数描述
    <description></description>                                                                     函数名
    <name>contains</name>                                                                           函数对应的类
    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>                函数对应的类中需要执行的方法
    <function-signature>boolean contains(java.lang.String, java.lang.String)</function-signature>
    <example>
      &lt;c:if test="${fn:contains(name, searchString)}">                                           例子
    </example>
  </function>

6、EL标签怎么使用,函数就怎么使用

7、自定义的标签的步骤

    *在WEB-INF目录下新建egov.tld文件,从fn.tld文件中拷贝模板

    *编写一个类,在该类中编写一个方法,该方法必须是public的,并且必须是static的

    *使用即可

猜你喜欢

转载自blog.csdn.net/qq_45796208/article/details/108851273