• JavaWeb 学习之 JSTL


      上一篇博文我们讲解了 MVC 小案例,案例中包含了基本的增、删、改、查,对这个案例的有兴趣的伙伴可以自己动手实践一下,去复习一下或者说是学点新的知识!如果有已经看过且实践过的伙伴相信对 JSP 页面中的 Java 代码很是烦躁。在 JSP 页面上写 Java 代码不仅影响美观而且对很容易写错我们想写的逻辑代码,我们今天所讲的 JSTL 就可以完美解决在 JSP 页面上写 Java 代码的缺点。在开始讲解 JSTL 之前我们先讲解一下 EL、自定义 JSTL等知识点。

      EL(Expression Language) 是为了使JSP写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。

      1. 所有的 EL 表达式都是以 ${ 开头,以 结尾,我们先来举一个例子体会一下 EL 表达式相比于 Java 代码的优势,如: ${sessionScope.user.sex} ,表示的是在隐藏域 session 范围里找 user 属性,然后在 user 对象中找 sex 属性,它等同于 JSP 页面中的 Java 代码,如下:

    1 User user = (User)session.getAttribute(“user”);
    2 String sex = user.getSex();

      2. EL 运算符 [ ] .

        1). [ ] 等同于 . 运算符,如上面的 EL 表达式等同于   ${sessionScope.user[“sex”]} ;

        2). [ ] 运算符可以结合下标打印数组或者集合的值,如:  ${sessionScope.shoppingCart[0].price  表示在 session 属性范围内找到属性 shoppingCart 的集合对象,然后打印其第一行的 price 属性;

        3). 如果属性名为  com.javaweb.el  那我们就应该使用 [ ] 运算符去操作属性;

        4). EL 表达式不可以进行遍历数组集合的遍历。

      3. EL 表达式的查找顺序

        - 对于 EL 表达式  ${userName}  由于我们没有指定其属性范围,那么 EL 会从 page、request、session、application 四个隐藏属性中依次查找属性名为 userName 的属性,如果在哪一个隐藏域中找到就返回不再继续查找,如果找完了还没有找到就返回 NULL

      4. EL 隐含对象

        1). param 获取请求参数

        2). paramValues 获取一组请求参数,返回类型为数组,可以使用 [] 和小标的形式打印其中某一个数据

      5. EL 表达式会自动进行强制转换

        - EL 表达式可以进行自动的强制类型转换,如: ${param.count + 20}   就是将获取请求参数 count 后加上 20,假如请求参数 count 的值是 10,那么打印结果将会是 30,而不是 1020,因为 EL 表达式会进行自动的类型转换。

      6. . 运算符

        - EL 表达式获取到结果是对象,并且该对象有无参的 get 方法,那么就可以使用 . 运算符调用该方法,并且可以一直调用下去,如: ${sessionScope.time.time} 等同于  

    Session.setAttribute(“time”, new Date() );
    new Date.getTime()

      7. 其他隐含对象

        1). initParam 获取当前 WEB 应用的初始化参数

        2). pageContext 可以用来获取当前 WEB 应用的根路径  ${pageContext.request.contextPath} 

        3). Cookie   ${cookie.JSESSIONID.name} ${cookie.JSESSIONID.value} 

        4). empty 运算符,如: ${empty param.name}  是判断输入框 name 属性是否为空,为空返回 true, 否则返回 false

      自定义 JSTL 标签

        1.  自定义标签分为空标签、带内容的标签、带属性的标签、带属性和带内容的标签、带有父标签的标签

        2. 开发自定义标签的核心就是编写标签处理器

        3. 步骤

          1). 编写完成标签功能的 Java 类(标签处理器)

            a. 编写标签处理器,新建 Java 类,实现 SimpleTag 接口

            b. 接口方法介绍:

              -1. SetJspContext  JSP 引擎将代表页面的 pageContext 对象传递给标签处理器对象 ,JSPContext 是 pageContext 的父类由其可获得其他八个隐含对象

              -2. setParent JSP 引擎将父标签处理器对象传给当前标签处理器对象,只有存在父标签时 JSP 引擎才回调用该方法

              -3. SetXxx 设置标签属性,只有定义了属性才回调用该方法

              -4. setJSPBody 若存在标签体,JSP 引擎把标签体封装为一个 JSPFragment 对象,调用 SetJspBody 方法将 JSPFragment 对象传递给标签处理器,若标签体为空 JSP 引擎则不会调用该方法

              -5. doTag 此方法是标签执行逻辑代码的主要方法

          2). 编写标签库的描述文件(.tld),在 tld 文件对自定义标签进行描述

          3). 在 JSP 页面导入和使用自定义标签

        4. 编写带属性的自定义标签(我们自定义一个带有 count 属性和 attr 属性的标签,该标签的功能是将 attr 属性值打印在页面上,并打印 count 次)

          1). 步骤如上所说,代码如下:

            a. 标签处理器类

     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspContext;
     4 import javax.servlet.jsp.JspException;
     5 import javax.servlet.jsp.PageContext;
     6 import javax.servlet.jsp.tagext.JspFragment;
     7 import javax.servlet.jsp.tagext.JspTag;
     8 import javax.servlet.jsp.tagext.SimpleTag;
     9 import java.io.IOException;
    10 
    11 public class SimpleTagHelloWorld implements SimpleTag {
    12 
    13 //    当设置属性时调用属性名对应的 setXxx 方法;需要首先在 tld 文件中描述其标签属性
    14 //    建议将所有的属性都声明为 String 类型
    15     private String attr;
    16     private String count;
    17     private PageContext pageContext;
    18 
    19     public void setAttr(String attr) {
    20         this.attr = attr;
    21     }
    22     public void setCount(String count) {
    23         this.count = count;
    24     }
    25 
    26     //    标签执行的逻辑代码,每次都会执行的方法
    27     @Override
    28     public void doTag() throws JspException, IOException {
    29         System.out.println(attr);
    30         System.out.println(count);
    31 
    32 //        从 url 中获取请求参数 name 的值,并将其打印 count 次
    33         int c;
    34         c = Integer.parseInt(count);
    35         for (int i = 0; i < c; i++) {
    36             pageContext.getOut().print(attr + "<br>");
    37         }
    38     }
    39 
    40     @Override
    41     public void setParent(JspTag jspTag) {
    42         System.out.println("setParent");
    43     }
    44 
    45     @Override
    46     public JspTag getParent() {
    47         return null;
    48     }
    49 //    是 pageContext 的父类,可以获取到其他八个隐含对象,所以凡是 JSP 页面可以做的那么标签处理器都可以做
    50 //    由 JSP 引擎直接调用
    51     @Override
    52     public void setJspContext(JspContext jspContext) {
    53         this.pageContext = (PageContext) jspContext;
    54     }
    55 
    56     @Override
    57     public void setJspBody(JspFragment jspFragment) {
    58         System.out.println("setJspBody");
    59     }
    60 }

          b. .tld 文件(后面的 tld 文件将指贴出 tag 节点,因为其他部分为固定的)

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 
     3 <taglib xmlns="http://java.sun.com/xml/ns/javaee"
     4         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     5         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
     6         version="2.1">
     7 
     8     <tlib-version>1.0</tlib-version>
     9     <!--在页面所推荐使用的标签开头-->
    10     <short-name>hello</short-name>
    11     <!--在页面所要引用的 uri-->
    12     <uri>http://hello.world.com</uri>
    13 
    14     <tag>
    15         <!--标签名-->
    16         <name>world</name>
    17         <!--标签处理器全类名-->
    18         <tag-class>simple.myself.tag.helloworld.SimpleTagHelloWorld</tag-class>
    19         <!--标签体-->
    20         <body-content>empty</body-content>
    21         <!--设置属性-->
    22         <attribute>
    23             <!--属性名-->
    24             <name>attr</name>
    25             <!--设置是否为必须的属性-->
    26             <required>true</required>
    27             <!--runtime expression value, 设置是否可以接受表达式的值,如 EL-->
    28             <rtexprvalue>true</rtexprvalue>
    29         </attribute>
    30         <attribute>
    31             <name>count</name>
    32             <required>false</required>
    33             <rtexprvalue>false</rtexprvalue>
    34         </attribute>
    35     </tag>
    36 </taglib>

          c. JSP 页面上的使用(其中 attr 属性的值为获取请求参数的 name 属性值,我们可以直接在地址栏加上 name 属性,如 http://.....xxx.jsp?name=java)

     1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     2 <%--导入标签库--%>
     3 <%@taglib prefix="hello" uri="http://hello.world.com" %>
     4 <html>
     5 <head>
     6     <title>myselfTag</title>
     7 </head>
     8 <body>
     9   <h3>
    10       <hello:world attr="${param.name}" count="10"></hello:world>
    11   </h3>
    12 </body>
    13 </html>

        5. 带属性标签小练习(可以先思考,其代码在最后公布)

          1). 自定义一个标签,带有两个属性 max,min,执行标签将会打印两个属性中的最大值

          2). 自定义一个标签,带有一个属性 src,执行标签将会将文件的内容打印到桌面上

        6. 带标签体和带属性的标签

          1). 类似于上面,我们这次将标签体的内容打印 times 次,并将标签体的内容转换为大写

            a. 标签处理器类(这次我们直接继承 SimpleTagSupport 类,只需要实现 doTag 方法,方便了代码书写)

     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspException;
     4 import javax.servlet.jsp.PageContext;
     5 import javax.servlet.jsp.tagext.JspFragment;
     6 import javax.servlet.jsp.tagext.SimpleTagSupport;
     7 import javax.sql.rowset.JdbcRowSet;
     8 import java.io.IOException;
     9 import java.io.StringWriter;
    10 
    11 /**
    12  * Created by shkstart on 2017/11/21.
    13  */
    14 public class Times extends SimpleTagSupport {
    15 
    16     private String times;
    17 
    18     public void setTimes(String times) {
    19         this.times = times;
    20     }
    21 
    22     @Override
    23     public void doTag() throws JspException, IOException {
    24         PageContext pageContext = (PageContext) getJspContext();
    25             // 获取标签体,封装为 JSPFragment 对象
    26         JspFragment jspFragment = getJspBody();
    27         StringWriter stringWriter = new StringWriter();
    28             // 将标签体输出到 StringWriter,若 invoke 方法参数为 null 则直接输出到页面
    29         jspFragment.invoke(stringWriter);
    30         String content = stringWriter.toString().toUpperCase();
    31 
    32         int c = Integer.parseInt(times);
    33         for (int i = 0; i < c; i++) {
    34             pageContext.getOut().print(content + "<br>");
    35         }
    36     }
    37 }

          b. tld 文件

    1 <tag>
    2         <name>toUpTimes</name>
    3         <tag-class>simple.myself.tag.helloworld.Times</tag-class>
    4         <body-content>scriptless</body-content>
    5         <attribute>
    6             <name>times</name>
    7             <required>true</required>
    8         </attribute>
    9 </tag>

          c. 标签的使用

     1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     2 <%@taglib prefix="hello" uri="http://hello.world.com" %>
     3 <html>
     4 <head>
     5     <title>BodyAttr</title>
     6 </head>
     7 <body>
     8 <h3></h3>
     9   <hello:toUpTimes times="10">HelloWorldAgain</hello:toUpTimes>
    10 
    11 </body>
    12 </html>

        7. 带父标签的标签

          1. 我们利用父标签实现一个类似于 if ... else if ... else if ... else ... 的标签

          2. 标签包含了 choose(父标签)、when(子标签)、otherwise(子标签),类似于 if ... else if ... else ...

          3. 父标签和子标签只是在标签处理器上有联系(通过 getParent),而在 tld 描述文件上没有联系

          4. 新建三个标签处理器类,如下

            a. 标签处理器类 (顺序为 choose --> when --> otherwise)

     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspException;
     4 import javax.servlet.jsp.tagext.SimpleTagSupport;
     5 import java.io.IOException;
     6 
     7 /**
     8  * Created by shkstart on 2017/11/21.
     9  */
    10 public class Choose extends SimpleTagSupport {
    11 
    12 //    在父标签中创建一个变量,用于在子标签中的判断
    13     private boolean flag = true;
    14 
    15     public void setFlag(boolean flag) {
    16         this.flag = flag;
    17     }
    18 
    19     public boolean isFlag() {
    20         return flag;
    21     }
    22 
    23     @Override
    24     public void doTag() throws JspException, IOException {
    25 //        对于父标签来说,其标签体为子标签,所以直接打印标签体就是执行子标签
    26         getJspBody().invoke(null);
    27     }
    28 }
     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspException;
     4 import javax.servlet.jsp.tagext.JspTag;
     5 import javax.servlet.jsp.tagext.SimpleTagSupport;
     6 import java.io.IOException;
     7 
     8 /**
     9  * Created by shkstart on 2017/11/21.
    10  */
    11 public class When extends SimpleTagSupport {
    12 
    13     private boolean item;
    14 
    15     public void setItem(boolean item) {
    16         this.item = item;
    17     }
    18 
    19     @Override
    20     public void doTag() throws JspException, IOException {
    21         Choose jspTag = (Choose) getParent();
    22         boolean flag = jspTag.isFlag();
    23 
    24         if (item) {
    25             if (flag) {
    26 //                若父标签的标志为真,且子标签本身也为真,那么就执行子标签的标签的标签体,且将父标签的标志置为 false
    27                 getJspBody().invoke(null);
    28                 jspTag.setFlag(false);
    29             }
    30         }
    31     }
    32 }
     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspException;
     4 import javax.servlet.jsp.tagext.SimpleTagSupport;
     5 import java.io.IOException;
     6 
     7 /**
     8  * Created by shkstart on 2017/11/21.
     9  */
    10 public class OtherWise extends SimpleTagSupport {
    11 
    12     @Override
    13     public void doTag() throws JspException, IOException {
    14         Choose choose = (Choose) getParent();
    15         boolean flag = choose.isFlag();
    16 //        只需判断父标签是否为真,若执行了 when 那么就不会执行此操作,因为父标签的标志已经被置为 false
    17         if (flag) {
    18             getJspBody().invoke(null);
    19         }
    20     }
    21 }

          b. tld 文件

     1     <tag>
     2         <name>choose</name>
     3         <tag-class>simple.myself.tag.helloworld.Choose</tag-class>
     4         <body-content>scriptless</body-content>
     5     </tag>
     6     <tag>
     7         <name>when</name>
     8         <tag-class>simple.myself.tag.helloworld.When</tag-class>
     9         <body-content>scriptless</body-content>
    10         <attribute>
    11             <name>item</name>
    12             <required>true</required>
    13             <rtexprvalue>true</rtexprvalue>
    14         </attribute>
    15     </tag>
    16     <tag>
    17         <name>otherwise</name>
    18         <tag-class>simple.myself.tag.helloworld.OtherWise</tag-class>
    19         <body-content>scriptless</body-content>
    20     </tag>

          c. 使用(获取请求参数 age 的值,判断其值若是大于 25 则打印 DX,否则打印 XX),表面上看父标签和子标签没有直接上的联系,但是需要在父标签中新建标识控制子标签的执行与否

     1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     2 <%@ taglib prefix="hello" uri="http://hello.world.com" %>
     3 <html>
     4 <head>
     5     <title>Choose</title>
     6 </head>
     7 <body>
     8 <h3>
     9 <hello:choose>
    10     <hello:when item="${param.age > 25}">DX</hello:when>
    11     <hello:otherwise>XX</hello:otherwise>
    12 </hello:choose>
    13 </h3>
    14 </body>
    15 </html>

        8. 实现一个自定义的 forEach 标签,实现了对集合的遍历(JSTL 中的 forEach 可以对集合和 Map等进行遍历,这里我们实现对集合的遍历就好)

          1. 其必须包含属性 ietms 获取集合信息

          2. 其必须包含属性 var 存储当期所遍历的信息

          3. 将当前所遍历的集合数据存入域对象 pageContext 中,属性名为 var,值为当前遍历的对象

          4. 在页面上使用的时候不需要去指明其域对象范围,因为默认的便是从 pageContext 中查找

            a. 标签处理器类

     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspException;
     4 import javax.servlet.jsp.PageContext;
     5 import javax.servlet.jsp.tagext.JspFragment;
     6 import javax.servlet.jsp.tagext.SimpleTagSupport;
     7 import java.io.IOException;
     8 import java.util.List;
     9 
    10 /**
    11  * Created by shkstart on 2017/11/21.
    12  */
    13 public class ForEach extends SimpleTagSupport {
    14 
    15     private List<Object> items;
    16     private String var;
    17 
    18     public void setItems(List<Object> items) {
    19         this.items = items;
    20     }
    21 
    22     public void setVar(String var) {
    23         this.var = var;
    24     }
    25 
    26 //    自定义实现 forEach
    27 //    遍历 items 集合,并将该当前遍历的对象加入到 pageContext 中,键为 var, 值为正在遍历的对象
    28 //    在页面上若不加范围 默认的便是从 pageContext 开始查找,所以可以省略
    29     @Override
    30     public void doTag() throws JspException, IOException {
    31         PageContext pageContext = (PageContext) getJspContext();
    32 
    33         for (Object obj : items) {
    34             pageContext.setAttribute(var, obj);
    35             JspFragment jspFragment = getJspBody();
    36             jspFragment.invoke(null );
    37         }
    38     }
    39 }

            b. tld 描述文件

     1 <tag>
     2         <name>forEach</name>
     3         <tag-class>simple.myself.tag.helloworld.ForEach</tag-class>
     4         <body-content>scriptless</body-content>
     5 
     6         <attribute>
     7             <name>items</name>
     8             <required>true</required>
     9             <rtexprvalue>true</rtexprvalue>
    10         </attribute>
    11 
    12         <attribute>
    13             <name>var</name>
    14             <required>true</required>
    15             <rtexprvalue>false</rtexprvalue>
    16         </attribute>
    17 </tag>

            c. 页面上的使用(包含了在页面上模仿 Servlet 给集合中添加数据在请求转发到获取页面对其进行遍历)

     1 <%@ page import="com.java.jstl.domain.Customer" %>
     2 <%@ page import="java.util.List" %>
     3 <%@ page import="java.util.ArrayList" %>
     4 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     5 <html>
     6 <head>
     7     <title>Customer</title>
     8 </head>
     9 <body>
    10 <h3><%
    11     List<Customer> list = new ArrayList<Customer>();
    12     list.add(new Customer(1, "z", "x"));
    13     list.add(new Customer(2, "v", "q"));
    14     list.add(new Customer(3, "c", "w"));
    15     list.add(new Customer(4, "x", "e"));
    16 
    17     request.setAttribute("customer", list);
    18 %>
    19     <jsp:forward page="forEach.jsp"></jsp:forward>
    20 </body>
    21 </html>
     1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     2 <%@taglib prefix="hello" uri="http://hello.world.com" %>
     3 <html>
     4 <head>
     5     <title>ForEachOfMy</title>
     6 </head>
     7 <body>
     8 <h3>
     9   <hello:forEach items="${requestScope.customer}" var="customer">
    10         ${customer.id}, ${customer.name}, ${customer.address}<br>
    11   </hello:forEach>
    12 </h3>
    13 </body>
    14 </html>

        9. 我们上面要求大家自己去实现思考的自定义标签的代码

          1. 是求两个属性的最大值

     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspContext;
     4 import javax.servlet.jsp.JspException;
     5 import javax.servlet.jsp.PageContext;
     6 import javax.servlet.jsp.tagext.JspFragment;
     7 import javax.servlet.jsp.tagext.JspTag;
     8 import javax.servlet.jsp.tagext.SimpleTag;
     9 import java.io.IOException;
    10 
    11 /**
    12  * 此标签的功能是比较两个参数值,并输出比较大的值到页面
    13  */
    14 public class MaxMin implements SimpleTag {
    15 
    16     private String max;
    17     private String min;
    18     private PageContext pageContext;
    19 
    20     public void setMax(String max) {
    21         this.max = max;
    22     }
    23 
    24     public void setMin(String min) {
    25         this.min = min;
    26     }
    27 
    28     @Override
    29     public void doTag() throws JspException, IOException {
    30         int num1, num2;
    31         num1 = Integer.parseInt(max);
    32         num2 = Integer.parseInt(min);
    33 
    34         if (num1 > num2) {
    35             pageContext.getOut().print(num1 + "<br>");
    36             return;
    37          }
    38         pageContext.getOut().print(num2 + "<br>");
    39     }
    40 
    41     @Override
    42     public void setParent(JspTag jspTag) {
    43 
    44     }
    45 
    46     @Override
    47     public JspTag getParent() {
    48         return null;
    49     }
    50 
    51     @Override
    52     public void setJspContext(JspContext jspContext) {
    53         this.pageContext = (PageContext) jspContext;
    54     }
    55 
    56     @Override
    57     public void setJspBody(JspFragment jspFragment) {
    58 
    59     }
    60 }
     1  <tag>
     2         <name>max</name>
     3         <tag-class>simple.myself.tag.helloworld.MaxMin</tag-class>
     4         <body-content>empty</body-content>
     5         <attribute>
     6             <name>max</name>
     7             <required>true</required>
     8             <rtexprvalue>false</rtexprvalue>
     9         </attribute>
    10         <attribute>
    11             <name>min</name>
    12             <required>true</required>
    13             <rtexprvalue>false</rtexprvalue>
    14         </attribute>
    15     </tag>
     1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     2 <%--导入标签库--%>
     3 <%@taglib prefix="hello" uri="http://hello.world.com" %>
     4 <html>
     5 <head>
     6     <title>myselfTag</title>
     7 </head>
     8 <body>
     9   <h3>
    10       <%--<hello:world attr="${param.name}" count="10"></hello:world>--%>
    11       <hello:max max="20" min="50"></hello:max>
    12   </h3>
    13 </body>
    14 </html>

          2. 获取本地文件将其打印到页面

     1 package simple.myself.tag.helloworld;
     2 
     3 import javax.servlet.jsp.JspException;
     4 import javax.servlet.jsp.PageContext;
     5 import javax.servlet.jsp.tagext.SimpleTagSupport;
     6 import java.io.*;
     7 import java.util.regex.Pattern;
     8 
     9 /**
    10  * 此标签的功能是将文件输出到页面,
    11  * 如果要输出的文件中有<> 就需要利用正则表达式将其替换为 &lt&gt
    12  */
    13 public class IO extends SimpleTagSupport{
    14 
    15     private PageContext pageContext;
    16     private String src;
    17 
    18     public void setSrc(String src) {
    19         this.src = src;
    20     }
    21 
    22     @Override
    23     public void doTag() throws JspException, IOException {
    24 //        利用 Reader 读取字符文件
    25         File file = new File(src);
    26         pageContext = (PageContext) getJspContext();
    27 
    28         Reader reader = new FileReader(file);
    29 //        加上缓冲流加快读取速度
    30         BufferedReader bufferedReader = new BufferedReader(reader);
    31         String str;
    32 
    33         while((str = bufferedReader.readLine()) != null) {
    34 //            利用正则表达式将 <> 转义
    35             str = Pattern.compile("<").matcher(str).replaceAll("&lt");
    36             str = Pattern.compile(">").matcher(str).replaceAll("&gt");
    37             pageContext.getOut().print(str + "<br>");
    38         }
    39 
    40         bufferedReader.close();
    41         reader.close();
    42     }
    43 }
     1  <tag>
     2         <name>readFile</name>
     3         <tag-class>simple.myself.tag.helloworld.IO</tag-class>
     4         <body-content>empty</body-content>
     5         <attribute>
     6             <name>src</name>
     7             <required>true</required>
     8             <rtexprvalue>false</rtexprvalue>
     9         </attribute>
    10     </tag>
     1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     2 <%--导入标签库--%>
     3 <%@taglib prefix="hello" uri="http://hello.world.com" %>
     4 <html>
     5 <head>
     6     <title>myselfTag</title>
     7 </head>
     8 <body>
     9   <h3>
    10       <%--<hello:world attr="${param.name}" count="10"></hello:world>--%>
    11       <hello:max max="20" min="50"></hello:max>
    12       <hello:readFile src="C:UserslenovoDesktoperror.txt"></hello:readFile>
    13   </h3>
    14 </body>
    15 </html>

      

      到这里我们就将自定义简单标签讲完了,掌握了自定义 JSTL 标签那么对于学习 JSTL 就更加简单了,现在我们开始说一下 JSTL 吧。

        1. JSTL 有许多的标签库,我们最常用是核心标签库,我们在使用之前首先需要将其 jar 包加入到 lib 目录下,对于 IDEA 需要新建 lib 目录;

        2.  <c:out value=""></c:out>  等同于  <%= %> ,但是 c:out 标签可以对敏感字符进行自动转换,如: <>,Value 值可以是 EL 表达式,但单独使用 EL 表达式将不会转换敏感字符

        3.  <c:set var=”属性名” value=”属性值” scope=””></c:set>  value 属性值可以使用 EL 表达式赋值,c:set 直接在指定范围放置属性

        4. c:set 也可以为某域对象的范围内的某 JavaBean 对象赋值 (其中 request 范围内的 cust 属性为某一 JavaBean 对象)

    <c:set target=”${requestScope.cust }” property=”id” value=”${param.id }”></c:set>

        5.  <c:if test=""></c:if>  test 表达式的值若为 true,则打印标签体,我们还可以利用 scope 和 var 属性将 boolean 结果存储到域对象中,以便后面的使用。但是没有对应的 else 标签(我们可以利用 choose when otherwise 实现 if else)

        6.  <c:forEach items=""></c:forEach> 可以实现对集合、map、数组进行遍历,其还有属性 begin、 end 、step、 var、 item、varStatus

          1).begin 表示从哪个下标开始(默认从 0 开始)

          2). end 表示遍历到哪结束

          3). step 表示每次遍历后增加几(默认为 1)

          4). var 将当前查询的数据保存到键为 var 属性的 pageContext 中

          5). item 从域对象中获取结合数据

          6). varStatus 属性还有拥有 index 、count、 first 、last

            a. index 表示当前所操作的下标

            b. count 表示当前所操作的对象是第几个

            c. first 返回 boolean 值,表示当前对象是不是第一个(所操作范围之内,即第一个打印的其值为  true,并不是整个集合的第一个,取决于 begin 的值)

            d. last 返回 boolean 值,表示当前对象是不是最后一个(所操作范围之内,即最后一个打印的其值为 true,并不是整个集合的最后一个,取决于 end 的值)

      上面的这些就是我们今天所讲的内容,对于 JSTL 的核心标签库我们还没有讲完,更不用说其他的标签库,但是我们给大家讲解了如何自定义 JSTL 标签,所以对自己感兴趣的标签可以去阅读源代码,相信大家掌握了自定义标签应该对阅读源代码没有多大的难点。

      谢谢阅读,希望对您有用,有不对的地方或者更好的建议还望指出!

  • 相关阅读:
    [Noip2017]逛公园
    [NOI2005]瑰丽华尔兹
    codeforces 558E A Simple Task
    bzoj1812 riv(树形背包)
    bzoj 1009 GT考试
    bzoj1030 文本生成器 Trie图+dp
    bzoj1500 维修数列(splay)
    [NOI2008]假面舞会
    测试用例的基本知识
    使用Xmind编写测试用例
  • 原文地址:https://www.cnblogs.com/bgzyy/p/7901137.html
Copyright © 2020-2023  润新知