• java web--自定义jstl标签


       1、 自定义标签

             1). HelloWorld

                       ①. 创建一个标签处理器类: 实现 SimpleTag 接口.
                       ②. 在 WEB-INF 文件夹下新建一个 .tld(标签库描述文件) 为扩展名的 xml 文件. 并拷入固定的部分: 并对
                             description, display-name, tlib-version, short-name, uri 做出修改

                            <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>JSTL 1.1 core library</description>
                                         <display-name>JSTL core</display-name>
                                         <tlib-version>1.1</tlib-version>
                                        <short-name>c</short-name>
                                        <uri>http://java.sun.com/jsp/jstl/core</uri>
                             </taglib>

                         ③. 在 tld 文件中描述自定义的标签:

                                               <!-- 描述自定义的 HelloSimpleTag 标签 -->
                                      <tag>
                                               <!-- 标签的名字: 在 JSP 页面上使用标签时的名字 -->
                                         <name>hello</name>
                                                <!-- 标签所在的全类名 -->
                                         <tag-class>com.atguigu.javaweb.tag.HelloSimpleTag</tag-class>
                                                <!-- 标签体的类型 -->
                                         <body-content>empty</body-content>
                                      </tag>
                         ④. 在 JSP 页面上使用自定义标签:

                               > 使用 taglib 指令导入标签库描述文件: <%@taglib uri="http://www.atguigu.com/mytag/core" prefix="atguigu" %>
                               > 使用自定义的标签: <atguigu:hello/>
                  2). setJspContext: 一定会被 JSP 引擎所调用, 先于 doTag, 把代表 JSP 引擎的 pageContext 传给标签处理器类.

                             private PageContext pageContext;
                                @Override
                                public void setJspContext(JspContext arg0) {
                                            System.out.println(arg0 instanceof PageContext);
                                            this.pageContext = (PageContext) arg0;
                                }

                  3). 带属性的自定义标签:

                           ①. 先在标签处理器类中定义 setter 方法. 建议把所有的属性类型都设置为 String 类型.

                              private String value;
                              private String count;

                                public void setValue(String value) {
                                         this.value = value;
                                    }

                                public void setCount(String count) {
                                        this.count = count;
                                   }

                           ②. 在 tld 描述文件中来描述属性: 

                                          <!-- 描述当前标签的属性 -->
                                 <attribute>
                                         <!-- 属性名, 需和标签处理器类的 setter 方法定义的属性相同 -->
                                 <name>value</name>
                                         <!-- 该属性是否被必须 -->
                                 <required>true</required>
                               <!-- rtexprvalue: runtime expression value
                                    当前属性是否可以接受运行时表达式的动态值 -->
                                    <rtexprvalue>true</rtexprvalue>
                               </attribute>

                             ③. 在页面中使用属性, 属性名同 tld 文件中定义的名字.

                                      <atguigu:hello value="${param.name }" count="10"/>

                       4). 通常情况下开发简单标签直接继承 SimpleTagSupport 就可以了. 可以直接调用其对应的 getter 方法得到对应的 API

                                   public class SimpleTagSupport implements SimpleTag{
                                            public void doTag()
                                            throws JspException, IOException{}
                                            private JspTag parentTag;
                                       public void setParent( JspTag parent ) {
                                                     this.parentTag = parent;
                                               }
                                       public JspTag getParent() {
                                                     return this.parentTag;
                                              }
                                       private JspContext jspContext;
                                       public void setJspContext( JspContext pc ) {
                                              this.jspContext = pc;
                                                 }
                                       protected JspContext getJspContext() {
                                                   return this.jspContext;
                                                   }
                                       private JspFragment jspBody;
                                       public void setJspBody( JspFragment jspBody ) {
                                                this.jspBody = jspBody;
                                                  }
                                       protected JspFragment getJspBody() {
                                                   return this.jspBody;
                                                   }
                                        }

        2. JSTL:

                      1)*. c:out 主要用于对特殊字符进行转换. 真正进行输出时, 建议使用 c:out, 而不是使用 EL
                      2)*. c:set: 可以为域赋属性值。 而对域对象中的 JavaBean 的属性赋值用的并不多.
                      3). c:remove: 移除指定域对象的指定属性值(较少使用, 即便移除也是在 Servlet 中完成)

                      4)*. c:if: 在页面上对现实的内容进行过滤, 把结果存储到域对象的属性中. 但不灵活, 会被其他的自定义标签所取代.
                       5). c:choose, c:when, c:otherwise: 作用同上, 但麻烦, 不灵活.

                      6)*. c:forEach: 对集合进行遍历的. 常用!
                      7). c:forTokens: 处理字符串, 类似于 String 累的 split() 方法(知道即可)

                      8). c:import: 导入页面到当前页面的. (了解)
                      9). c:redirect: 当前页面进行重定向的. (使用较少)
                     10)*. c:url: 产生一个 URL 的, 可以进行 URL 重写, 变量值编码, 较为常用.

         3. 开发有父标签的标签:

                       1). 父标签无法获取子标签的引用, 父标签仅把子标签作为标签体来使用.

                       2). 子标签可以通过 getParent() 方法来获取父标签的引用(需继承 SimpleTagSupport 或自实现 SimpleTag 接口的该方法):
                             若子标签的确有父标签, JSP 引擎会把代表父标签的引用通过 setParent(JspTag parent) 赋给标签处理器

                       3). 注意: 父标签的类型是 JspTag 类型. 该接口是一个空接口, 但是来统一 SimpleTag 和 Tag 的. 实际使用需要进行类型的强制转换.

                       4). 在 tld 配置文件中, 无需为父标签有额外的配置. 但, 子标签是是以标签体的形式存在的, 所以父标签的

                           <body-content></body-content>      需设置为 scriptles

                       5). 实现

                                   <c:choose>
                                             <c:when test="${param.age > 24}">大学毕业</c:when>
                                            <c:when test="${param.age > 20}">高中毕业</c:when>
                                            <c:otherwise>高中以下...</c:otherwise>
                                  </c:choose>

                         > 开发 3 个标签: choose, when, otherwise
                         > 其中 when 标签有一个 boolean 类型的属性: test
                         > choose 是 when 和 otherwise 的父标签
                         > when 在 otherwise 之前使用
                         > 在父标签 choose 中定义一个 "全局" 的 boolean 类型的 flag: 用于判断子标签在满足条件的情况下是否执行.
                                    * 若 when 的 test 为 true, 且 when 的父标签的 flag 也为 true, 则执行 when 的标签体(正常输出标签体的内容),
                                        同时把 flag 设置为 false
                                   * 若 when 的 test 为 true, 且 when 的父标签的 flag 为 false, 则不执行标签体.
                                   * 若 flag 为 true, otherwise 执行标签体.

        4. 带标签体的自定义标签:

                         1). 若一个标签有标签体:

                            <atguigu:testJspFragment>abcdefg</atguigu:testJspFragment>

                                在自定义标签的标签处理器中使用 JspFragment 对象封装标签体信息.

                         2). 若配置了标签含有标签体, 则 JSP 引擎会调用 setJspBody() 方法把 JspFragment 传递给标签处理器类
                               在 SimpleTagSupport 中还定义了一个 getJspBody() 方法, 用于返回 JspFragment 对象.

                        3). JspFragment 的 invoke(Writer) 方法: 把标签体内容从 Writer 中输出, 若为 null,
                                则等同于 invoke(getJspContext().getOut()), 即直接把标签体内容输出到页面上

                                有时, 可以 借助于 StringWriter, 可以在标签处理器类中先得到标签体的内容:

                             //1. 利用 StringWriter 得到标签体的内容.
                                     StringWriter sw = new StringWriter();
                                      bodyContent.invoke(sw);

                              //2. 把标签体的内容都变为大写
                                       String content = sw.toString().toUpperCase();

                         4). 在 tld 文件中, 使用 body-content 节点来描述标签体的类型:

                             <body-content>: 指定标签体的类型, 大部分情况下, 取值为 scriptless。可能取值有 3 种:
                                   empty: 没有标签体
                                   scriptless: 标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素
                                   tagdependent: 表示标签体交由标签本身去解析处理。
                                  若指定 tagdependent,在标签体中的所有代码都会原封不动的交给标签处理器,而不是将执行结果传递给标签处理器

                                <body-content>tagdependent</body-content

           5. 定义一个自定义标签: <atguigu:printUpper time="10">abcdefg</atguigu>

                             把标签体内容转换为大写, 并输出 time 次到 浏览

          6. 实现 forEach 标签:

                                 > 两个属性: items(集合类型, Collection), var(String 类型)
                                 > doTag:
                                         * 遍历 items 对应的集合
                                         * 把正在遍历的对象放入到 pageContext 中, 键: var, 值: 正在遍历的对象.
                                        * 把标签体的内容直接输出到页面上.

                                <c:forEach items="${requestScope.customers }" var="cust2">
                                         ${pageScope.cust2.id } -- ${cust2.name } <br>
                                </c:forEach>
                                <atguigu:saveAsFile src="d:\haha.txt">
                                       abcde
                                </atguigu>

         7.代码区

    package com.atguigu.javaweb.tag;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspContext;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.PageContext;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.JspTag;
    import javax.servlet.jsp.tagext.SimpleTag;
    
    public class HelloSimpleTag implements SimpleTag {
    
        private String value;
        private String count;
        
        public void setValue(String value) {
            this.value = value;
        }
        
        public void setCount(String count) {
            this.count = count;
        }
        
        //标签体逻辑实际应该编写到该方法中. 
        @Override
        public void doTag() throws JspException, IOException {
    //        System.out.println("value: " + value  + ", count: " + count);
    //        
    //        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
    //        pageContext.getOut().print("Hello: " + request.getParameter("name"));
            
            JspWriter out = pageContext.getOut();
            int c = 0;
            
            c = Integer.parseInt(count);
            for(int i = 0; i < c; i++){
                out.print((i + 1) + ": " + value);
                out.print("<br>");
            }
        }
    
        @Override
        public JspTag getParent() {
            System.out.println("getParent");
            return null;
        }
    
        @Override
        public void setJspBody(JspFragment arg0) {
            System.out.println("setJspBody");
        }
    
        private PageContext pageContext;
        
        //JSP 引擎调用, 把代表 JSP 页面的 PageContext 对象传入
        //PageContext 可以获取 JSP 页面的其他 8 个隐含对象. 
        //所以凡是 JSP 页面可以做的标签处理器都可以完成. 
        @Override
        public void setJspContext(JspContext arg0) {
            System.out.println(arg0 instanceof PageContext);  
            this.pageContext = (PageContext) arg0;
        }
    
        @Override
        public void setParent(JspTag arg0) {
            System.out.println("setParent");
        }
    
    }
    HelloSimpleTag
    package com.atguigu.javaweb.tag;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspContext;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.PageContext;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.JspTag;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class MaxTag extends SimpleTagSupport{
    
        private String num1;
        private String num2;
        
        public void setNum1(String num1) {
            this.num1 = num1;
        }
        
        public void setNum2(String num2) {
            this.num2 = num2;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            int a = 0;
            int b = 0;
            
            PageContext pageContext = (PageContext) getJspContext();
            
            JspWriter out = pageContext.getOut();
            
            try {
                a = Integer.parseInt(num1);
                b = Integer.parseInt(num2);
                out.print(a > b ? a : b);
            } catch (Exception e) {
                out.print("输入的属性的格式不正确!");
            }
            
        }
    
    }
    MaxTag
    package com.atguigu.javaweb.tag;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.regex.Pattern;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.PageContext;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class ReadFileTag extends SimpleTagSupport{
    
        //相对于当前 WEB 应用的根路径的文件名
        private String src;
    
        public void setSrc(String src) {
            this.src = src;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            PageContext pageContext = (PageContext) getJspContext();
            InputStream in = pageContext.getServletContext().getResourceAsStream(src);
            BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
            
            String str = null;
            while((str = reader.readLine()) != null){
                
                str = Pattern.compile("<").matcher(str).replaceAll("&lt");
                str = Pattern.compile(">").matcher(str).replaceAll("&gt");
                
                pageContext.getOut().println(str);
                pageContext.getOut().println("<br>"); 
            }
        }
        
    }
    ReadFileTag
    <?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">
    
        <!-- 描述 TLD 文件 -->
        <description>MyTag 1.0 core library</description>
        <display-name>MyTag core</display-name>
        <tlib-version>1.0</tlib-version>
    
        <!-- 建议在 JSP 页面上使用的标签的前缀 -->
        <short-name>atguigu</short-name>
        <!-- 作为 tld 文件的 id, 用来唯一标识当前的 TLD 文件, 多个 tld 文件的 URI 不能重复. 通过 JSP 页面的 taglib 
            标签的 uri 属性来引用. -->
        <uri>http://www.atguigu.com/mytag/core</uri>
    
        <tag>
            <name>readerFile</name>
            <tag-class>com.atguigu.javaweb.tag.ReadFileTag</tag-class>
            <body-content>empty</body-content>
    
            <attribute>
                <name>src</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
    
        <tag>
            <name>max</name>
            <tag-class>com.atguigu.javaweb.tag.MaxTag</tag-class>
            <body-content>empty</body-content>
    
            <attribute>
                <name>num1</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
    
            <attribute>
                <name>num2</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
    
        <!-- 描述自定义的 HelloSimpleTag 标签 -->
        <tag>
            <!-- 标签的名字: 在 JSP 页面上使用标签时的名字 -->
            <name>hello</name>
    
            <!-- 标签所在的全类名 -->
            <tag-class>com.atguigu.javaweb.tag.HelloSimpleTag</tag-class>
            <!-- 标签体的类型 -->
            <body-content>empty</body-content>
    
            <!-- 描述当前标签的属性 -->
            <attribute>
                <!-- 属性名 -->
                <name>value</name>
                <!-- 该属性是否被必须 -->
                <required>true</required>
                <!-- rtexprvalue: runtime expression value 当前属性是否可以接受运行时表达式的动态值 -->
                <rtexprvalue>true</rtexprvalue>
            </attribute>
    
            <attribute>
                <name>count</name>
                <required>false</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
        </tag>
    
    </taglib>  
    mytag.tld
    测试数据
    note.txt
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name>day_36</display-name>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    web.xml
    <%@page import="com.atguigu.javaweb.Customer"%>
    <%@page import="java.util.ArrayList"%>
    <%@page import="java.util.List"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        
        
        <jsp:forward page="test.jsp?a=1&b=2&name=java"></jsp:forward>
        
    </body>
    </html>
    index.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!-- 导入标签库(描述文件) -->    
    <%@taglib uri="http://www.atguigu.com/mytag/core" prefix="atguigu" %>
        
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
          //读取文件信息
        <atguigu:readerFile src="/WEB-INF/note.txt"/>
    
        <br><br>
        //比较a  b  值大小
        <atguigu:max num2="${param.a }" num1="${param.b }"/>
        
        <br>
        // name的值打印十遍
        <atguigu:hello value="${param.name }" count="10"/>
        
    </body>
    </html>
    test.jsp

     

    package com.atguigu.javaweb;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class ChooseTag extends SimpleTagSupport {
        
        private boolean flag = true;
        
        public void setFlag(boolean flag) {
            this.flag = flag;
        }
        
        public boolean isFlag() {
            return flag;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            getJspBody().invoke(null);
        }
    }
    ChooseTag
    package com.atguigu.javaweb;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class WhenTag extends SimpleTagSupport{
    
        private boolean test;
        
        public void setTest(boolean test) {
            this.test = test;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            if(test){
                
                ChooseTag chooseTag = (ChooseTag) getParent();
                boolean flag = chooseTag.isFlag();
                
                if(flag){
                    getJspBody().invoke(null);
                    chooseTag.setFlag(false);
                }
                
            }
        }
        
    }
    WhenTag
    package com.atguigu.javaweb;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class OtherwiseTag extends SimpleTagSupport{
    
        @Override
        public void doTag() throws JspException, IOException {
            ChooseTag chooseTag = (ChooseTag) getParent();
            
            if(chooseTag.isFlag()){
                getJspBody().invoke(null);
            }
        }
        
    }
    OtherwiseTag
    package com.atguigu.javaweb;
    
    import java.io.IOException;
    import java.util.Collection;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class ForEachTag extends SimpleTagSupport{
    
        private Collection<?> items;
        
        public void setItems(Collection<?> items) {
            this.items = items;
        }
        
        private String var;
        
        public void setVar(String var) {
            this.var = var;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
    //        * 遍历 items 对应的集合
            if(items != null){
                for(Object obj: items){
            //        * 把正在遍历的对象放入到 pageContext 中, 键: var, 值: 正在遍历的对象. 
                    getJspContext().setAttribute(var, obj);
                    
                    //把标签体的内容直接输出到页面上. 
                    getJspBody().invoke(null); 
                    
                }
            }
            
        }
        
    }
    ForEachTag
    package com.atguigu.javaweb;
    
    public class Customer {
    
        private Integer id;
        private String name;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Customer(Integer id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
    
        public Customer() {
            // TODO Auto-generated constructor stub
        }
    
    }
    Customer
    package com.atguigu.javaweb;
    
    public class MyELFunction {
        
        public static String concat(String str1, String str2){
            return str1 + str2;
        }
        
    }
    MyELFunction
    package com.atguigu.javaweb;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class ParentTag extends SimpleTagSupport {
        
        private String name = "www.ATGUIGU.com";
        
        public String getName() {
            return name;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            System.out.println("父标签的标签处理器类 name: " + name);
            getJspBody().invoke(null);
        }
        
    }
    ParentTag
    package com.atguigu.javaweb;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspTag;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class SonTag extends SimpleTagSupport {
        
        @Override
        public void doTag() throws JspException, IOException {
            //1. 得到父标签的引用
            JspTag parent = getParent();
            
            //2. 获取父标签的 name 属性
            ParentTag parentTag = (ParentTag) parent;
            String name = parentTag.getName();
            
            //3. 把 name 值打印到 JSP 页面上.
            getJspContext().getOut().print("子标签输出name: " + name);
        }
        
    }
    SonTag
    package com.atguigu.javaweb;
    
    import java.io.IOException;
    import java.io.StringWriter;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class PrintUpperTag extends SimpleTagSupport {
    
        private String time;
        
        public void setTime(String time) {
            this.time = time;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            //1. 得到标签体的内容
            JspFragment bodyContent = getJspBody();
            StringWriter sw = new StringWriter();
            bodyContent.invoke(sw);
            String content = sw.toString();
            
            //2. 变为大写
            content = content.toUpperCase();
            
            //3. 得到 out 隐含变量
            //4. 循环输出
            int count = 1;
            try {
                count = Integer.parseInt(time);
            } catch (Exception e) {}
            for(int i = 0; i < count; i++){
                getJspContext().getOut().print(i + 1 + "." + content + "<br>");
            }
        }
        
    }
    PrintUpperTag
    package com.atguigu.javaweb;
    
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class TestJspFragment extends SimpleTagSupport {
        
        @Override
        public void doTag() throws JspException, IOException {
            JspFragment bodyContent = getJspBody();
            //JspFragment.invoke(Witer): Writer 即为标签体内容输出的字符流, 若为 null, 则
            //输出到 getJspContext().getOut(), 即输出到页面上.
            
            //1. 利用 StringWriter 得到标签体的内容.
            StringWriter sw = new StringWriter();
            bodyContent.invoke(sw);
            
            //2. 把标签体的内容都变为大写
            String content = sw.toString().toUpperCase();
            
            //3. 获取 JSP 页面的 out 隐含对象, 输出到页面上
            getJspContext().getOut().print(content);
        }
        
    }
    TestJspFragment
    <?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>MyTag 1.2 core library</description>
        <display-name>MyTag core</display-name>
        <tlib-version>1.2</tlib-version>
        <short-name>atguigu</short-name>
        <uri>http://atguigu.com/myTag/core</uri>
    
        <tag>
            <name>testJspFragment</name>
            <tag-class>com.atguigu.javaweb.TestJspFragment</tag-class>
            <body-content>tagdependent</body-content>
        </tag>
        
        <tag>
            <name>printUpper</name>
            <tag-class>com.atguigu.javaweb.PrintUpperTag</tag-class>
            <body-content>scriptless</body-content>
            
            <attribute>
                <name>time</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
        
        <tag>
            <name>forEach</name>
            <tag-class>com.atguigu.javaweb.ForEachTag</tag-class>
            <body-content>scriptless</body-content>
            
            <attribute>
                <name>items</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
            
            <attribute>
                <name>var</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
    <!--empty: 没有标签体    
    scriptless: 标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素
    tagdependent: 表示标签体交由标签本身去解析处理。
    -->    
        <tag>
            <name>parentTag</name>
            <tag-class>com.atguigu.javaweb.ParentTag</tag-class>
            <body-content>scriptless</body-content>
        </tag>
        <tag>
            <name>sonTag</name>
            <tag-class>com.atguigu.javaweb.SonTag</tag-class>
            <body-content>empty</body-content>
        </tag>
    
        <tag>
            <name>choose</name>
            <tag-class>com.atguigu.javaweb.ChooseTag</tag-class>
            <body-content>scriptless</body-content>
        </tag>
        
        <tag>
            <name>when</name>
            <tag-class>com.atguigu.javaweb.WhenTag</tag-class>
            <body-content>scriptless</body-content>
            
            <attribute>
                <name>test</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
        
        <tag>
            <name>otherwise</name>
            <tag-class>com.atguigu.javaweb.OtherwiseTag</tag-class>
            <body-content>scriptless</body-content>
        </tag>
        
        <!-- 描述 EL 的自定义函数 -->
        <function>    
            <name>concat</name>
            <function-class>com.atguigu.javaweb.MyELFunction</function-class>
            <function-signature>java.lang.String concat(java.lang.String, java.lang.String)</function-signature>
        </function>
    
    </taglib>
    mytag.tld
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name>day_37</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    web.xml
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <jsp:forward page="/test.jsp?name=qwe&age=30&name1=abcdf&name2=efg"></jsp:forward>
    </body>
    </html>
    index.jsp
    <%@page import="java.util.HashMap"%>
    <%@page import="java.util.Map"%>
    <%@page import="java.util.ArrayList"%>
    <%@page import="java.util.List"%>
    <%@page import="com.atguigu.javaweb.Customer"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <h4>
            c:url 产生一个 url 地址. 可以 Cookie 是否可用来智能进行 URL 重写, 对 GET 请求的参数进行编码
            可以把产生的 URL 存储在域对象的属性中.
            还可以使用 c:param 为 URL 添加参数. c:url 会对参数进行自动的转码. 
            value 中的 / 代表的是当前 WEB 应用的根目录. 
        </h4>
        <c:url value="/test.jsp" var="testurl" scope="page">
            <c:param name="name" value="尚硅谷"></c:param>
        </c:url>
        
        url: ${testurl }
    
        <h4>
            c:redirect 使当前 JSP 页面重定向到指定的页面. 使当前 JSP 转发到指定页面可以使用
            <%--  
            <jsp:forward page="/test.jsp"></jsp:forward>    
            --%>
            / 代表的是当前 WEB 应用的根目录. 
            
            response.sendRedirect("/test.jsp") / 代表 WEB 站点的根目录
        </h4>
        <%-- 
        <c:redirect url="http://www.atguigu.com"></c:redirect>
        <c:redirect url="/test.jsp"></c:redirect>
        --%>
        
        <h4>c:import 可以包含任何页面到当前页面</h4>
        <c:import url="http://www.baidu.com"></c:import>
    
        <h4>c:forTokens: 处理字符串的, 类似于 String 的 split() 方法</h4>
        <c:set value="a,b,c.d.e.f;g;h;j" var="test" scope="request"></c:set>
        <c:forTokens items="${requestScope.test }" delims="." var="s">
            ${s }<br>
        </c:forTokens>
        
        <h4>c:forEach: 可以对数组, Collection, Map 进行遍历, begin(对于集合 begin 从 0 开始算), end, step</h4>
        <c:forEach begin="1" end="10" step="3" var="i">
            ${ i} --
        </c:forEach>
        <br><br>
        
        <% 
            List<Customer> custs = new ArrayList<Customer>();
            custs.add(new Customer(1, "AAA")); //index: 0 
            custs.add(new Customer(2, "BBB")); //1
            custs.add(new Customer(3, "CCC")); 
            custs.add(new Customer(4, "DDD")); //3
            custs.add(new Customer(5, "EEE"));
            custs.add(new Customer(6, "FFF")); //5
            
            request.setAttribute("custs", custs);
        %>
        
        <br><br>
        <!-- 遍历 Collection, 遍历数组同 Collection -->
        <c:forEach items="${requestScope.custs }" var="cust"
            varStatus="status">
            ${status.index}, ${status.count}, ${status.first}, ${status.last}: ${cust.id }: ${cust.name }<br>
        </c:forEach>
        
        <!-- 遍历 Map -->
        <% 
            Map<String, Customer> custMap = new HashMap<String, Customer>();
            custMap.put("a", new Customer(1, "AAA")); //index: 0 
            custMap.put("b", new Customer(2, "BBB")); //index: 0 
            custMap.put("c", new Customer(3, "CCC")); //index: 0 
            custMap.put("d", new Customer(4, "DDD")); //index: 0 
            custMap.put("e", new Customer(5, "EEE")); //index: 0 
            custMap.put("f", new Customer(6, "FFF")); //index: 0 
            
            request.setAttribute("custMap", custMap);
        %>
        
        <br><br>
        <c:forEach items="${requestScope.custMap }" var="cust">
            ${cust.key } - ${cust.value.id } - ${cust.value.name }<br>
        </c:forEach>
        
        <% 
            String [] names = new String[]{"A", "B", "C"};
            request.setAttribute("names", names);
        %>
        <br><br>
        <c:forEach var="name" items="${names }">${name }-</c:forEach>
        
        <br><br>
        <c:forEach items="${pageContext.session.attributeNames }" var="attrName">
            ${attrName }-
        </c:forEach>
        
        <h4>
            c:choose, c:when, c:otherwise: 可以实现 if...else if...else if...else 的效果. 但较为麻烦
            其中: c:choose 以 c:when, c:otherwise 的父标签出现.
            c:when, c:otherwise 不能脱离 c:choose 单独使用.
            c:otherwise 必须在 c:when 之后使用。 
        </h4>
        <c:choose>        
            <c:when test="${param.age > 60 }">
                老年
            </c:when>
            <c:when test="${param.age > 35 }">
                中年
            </c:when>
            <c:when test="${param.age > 18 }">
                青年
            </c:when>
            <c:otherwise>
                未成年. 
            </c:otherwise>
        </c:choose>
    
        <c:set value="20" var="age" scope="request"></c:set>
    
        <h4>c:if: 不能实现 else 操作, 但可以把结果储存起来。 </h4>
        <c:if test="${requestScope.age > 18 }">成年了!</c:if>
        <br><br>
        
        <c:if test="${param.age > 18 }" var="isAdult" scope="request"></c:if>
        isAdult: <c:out value="${requestScope.isAdult }"></c:out>
    
    
        <h4>c:remove: 移除指定域对象的指定属性值</h4>
        <c:set value="1997-09-1" var="date" scope="session"></c:set>
        date: ${sessionScope.date }
        <br><br>
    
        <c:remove var="date" scope="session"/>
        date: --${sessionScope.date }--
        <br><br>
        
        <h4>c:set: 可以为域赋属性值, 其中 value 属性支持 EL 表达式; 还可以为域对象中的 JavaBean 的属性赋值, target, value都支持 EL 表达式</h4>
        
        <c:set var="name" value="ATGUIGU" scope="page"></c:set>
        <%-- 
            pageContext.setAttribute("name", "atguigu");
        --%>
        name: ${pageScope.name }    
        
        <br><br>
        <c:set var="subject" value="${param.subject }" scope="session"></c:set>
        subject: ${sessionScope.subject }
        
        <br><br>
        <% 
            Customer cust = new Customer();
            cust.setId(1001);
            request.setAttribute("cust", cust);
        %>
        ID: ${requestScope.cust.id }
        <c:set target="${requestScope.cust }" property="id" value="${param.id }"></c:set>
        <br>
        ID: ${requestScope.cust.id }
        
        <br><br>
        
        <h4>c:out: 可以对特殊字符进行转换. </h4>
        
        <% 
            request.setAttribute("book", "<<Java>>");
        %>
        book: ${requestScope.book }
        <br><br>
        book: <c:out value="${requestScope.book }" default="booktitle"></c:out>
        
    </body>
    </html>
    jstl.jsp
    <%@page import="java.util.HashMap"%>
    <%@page import="java.util.Map"%>
    <%@page import="com.atguigu.javaweb.Customer"%>
    <%@page import="java.util.ArrayList"%>
    <%@page import="java.util.List"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="atguigu" uri="http://atguigu.com/myTag/core" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
          
           <!-- 把字母变成大写 -->
        <atguigu:testJspFragment>hello</atguigu:testJspFragment>
        <br><br>
        <!-- 把字母大写同时打印10遍 -->
        <atguigu:printUpper time="10">
            abcdefh
        </atguigu:printUpper>
        
        <br><br>
        <% 
            List<Customer> customers = new ArrayList<Customer>();
        
            customers.add(new Customer(1, "AAA"));
            customers.add(new Customer(2, "BBB"));
            customers.add(new Customer(3, "CCC"));
            customers.add(new Customer(4, "DDD"));
            customers.add(new Customer(5, "EEE"));
            
            request.setAttribute("customers", customers);
            
            Map<String, Customer> customerMap = new HashMap<String, Customer>();
            customerMap.put("a", customers.get(0));
            customerMap.put("b", customers.get(1));
            customerMap.put("c", customers.get(2));
            customerMap.put("d", customers.get(3));
            customerMap.put("e", customers.get(4));
            
            request.setAttribute("customerMap", customerMap); 
        %>
        
         <%-- 
        <atguigu:forEach items="${customerMap }" var="cust">
            --${pagecust.key } -- ${cust.value.id } -- ${cust.value.name } <br>
        </atguigu:forEach>
        
        <br><br>
         --%>
        <atguigu:forEach items="${requestScope.customers }" var="cust">
            --${pageScope.cust.id } -- ${cust.name } <br>
        </atguigu:forEach>    
        
            
        <br><br>
        
        <!-- 父标签打印name到控制台.  -->
        <atguigu:parentTag>
            <!-- 子标签以父标签的标签体存在,  子标签把父标签的name属性打印到 JSP 页面上.  -->
            <atguigu:sonTag/>
        </atguigu:parentTag>
        
        <br><br>
        
        <atguigu:choose>
            <atguigu:when test="${param.age > 24}">^大学毕业</atguigu:when>
            <atguigu:when test="${param.age > 20}">^高中毕业</atguigu:when>
            <atguigu:otherwise> ^高中以下...</atguigu:otherwise>
        </atguigu:choose>
        
        <!-- 使用一个 EL 的自定义函数 -->
        ${fn:length(param.name) } 
        <br><br>
        
        ${fn:toUpperCase(param.name1) }
            
        <br><br>
        <!-- 测试自定义的 EL 函数 -->
        ${atguigu:concat(param.name1, param.name2)}
        
    </body>
    </html>
    test.jsp
  • 相关阅读:
    一个list<Map>里map其中的一个字段的值相同,如何判断这个字段相同,就把这个map的其他字段存入另一个map中
    ES6---箭头函数()=>{} 与function的区别
    VSCode代码格式化快捷键及保存时自动格式化
    NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException
    响应数据中文乱码
    tomcat将静态资源写入到浏览器乱码问题
    mark一款全局搜索工具,可以搜索文本内容
    mpvue 开发微信小程序搭建项目
    h5返回上一页ios页面不刷新
    微信小程序去除页面滚动条
  • 原文地址:https://www.cnblogs.com/ou-pc/p/8287751.html
Copyright © 2020-2023  润新知