zoukankan      html  css  js  c++  java
  • JSP2 自定义标签

    实现步骤


    1. 实现自定义标签的处理类
      继承javax.servlet.jsp.tagext.SimpleTagSupport,并重写doTag方法
    2. 建立标签库配置文件
    3. 在jsp中使用自定义标签

    一个简单的标签


    文件目录结构

    src/main/java
        |---- cn.ljl.javaweb.demo.jsp2taglib.servlet
                  |---- HelloWorldServlet.java
        |---- cn.ljl.javaweb.demo.jsp2taglib
                  |---- HelloWordTag.java
    src/main/webapp
        |---- WEB-INF
                  |---- jsp2taglib
                            |---- demo.tld
        |---- demo/jsp2taglib
                  |---- helloword.jsp
    文件解析:
    • HelloWorldServlet.java
      一个Servlet,简单的forward到helloword.jsp;其实直接请求jsp也可以,只是考虑到MVC的原则添加了这个Servlet
    • HelloWorldTag.java
      自定义标签的处理类
    • demo.tld
      标签库配置文件,可以放在WEB-INF/下,或其任意子路径下。
    • helloword.jsp
      这个jsp使用了自定义的标签

    文件内容

    HelloWordTag.java

    package cn.ljl.javaweb.demo.jsp2taglib;
    import java.io.IOException;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    /**
     * 一个简单的标签实现类,在页面输出一行hello word内容.
     * @author lijinlong
     *
     */
    public class HelloWordTag extends SimpleTagSupport {
        @Override
        public void doTag() throws JspException, IOException {
            getJspContext().getOut().print("Hello World" + new java.util.Date());
        }
    }
    说明:
    1. 标签处理类应该继承javax.servlet.jsp.tagext.SimpleTagSupport
    2. 重写doTag方法,这个方法负责往页面写内容

    demo.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">
        <tlib-version>1.0</tlib-version>
        <short-name>demo</short-name>
        <uri>http://www.lijinlong.cn/demotaglib</uri>
        <tag>
            <description>输出Hello World,这个标签没有属性和标签体</description>
            <name>helloword</name>
            <tag-class>cn.ljl.javaweb.demo.jsp2taglib.HelloWordTag</tag-class>
            <body-content>empty</body-content>
        </tag>
    </taglib>
    tld是Tag Library Definition的缩写。每个tld文件定义一个标签库,一个标签库可以包含多个标签。
    根元素taglib定义标签库:
    • tlib-version
      标签库的版本号,对程序没有多少作用
    • short-name
      标签库的名称,对程序没有多少作用
    • uri
      标签库的唯一标识,这个很重要;JSP要根据这个来引入指定的标签库

    子元素tag用于定义标签,可以出现多次。tag元素常用的子元素如下:
    • description
      标签的描述性信息
    • name
      标签的名称,jsp中根据这个来指定使用的标签
    • tag-class
      标签的处理类
    • body-content
      标签体的类型
    • dynamic-attributes
      定义动态属性
     
    body-content的类型有:
    • tagdependent
      指定标签处理类自己负责处理标签体
    • empty
      只作为空标签来使用(比如<br />就是一个空标签)
    • scriptless
      标签体中不能含有JSP脚本。可以是静态的html、表达式语言。
    • JSP
      可以使用JSP脚本 - JSP2.0不再支持这个类型

    helloword.jsp

    <%@ page language="java" contentType="text/html; charset=GBK"
        pageEncoding="GBK"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@ taglib uri="http://www.lijinlong.cn/demotaglib" prefix="demo"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    <title>自定义标签 - Hello World</title>
    </head>
    <body>
    <h2>显示自定义标签 - Hello World的内容:</h2>
    <demo:helloword />
    </body>
    </html>
    使用自定义标签需要做两件事:
    1. 使用taglib编译指令,导入指定uri的标签库,并绑定到指定的prefix。
    2. 使用标签,以prefix:tagname的形式

    HelloWordServlet.java

    package cn.ljl.javaweb.demo.jsp2taglib.servlet;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    @WebServlet(name="helloWorldServlet", urlPatterns = {"/demo/jsp2taglib/helloword"})
    public class HelloWorldServlet extends HttpServlet {
        private static final long serialVersionUID = -297481388442806334L;
        
        private static final String VIEW_HELLOWORLD = "/demo/jsp2taglib/helloword.jsp";
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            req.getRequestDispatcher(VIEW_HELLOWORLD).forward(req, resp);
        }
        
    }

    测试

    支持属性的标签


    定义一个支持属性的标签 - add,它接收2个参数,并输出求和的结果。

    文件目录结构

    src/main/java
        |---- cn.ljl.javaweb.demo.jsp2taglib.servlet
                  |---- AddServlet.java
        |---- cn.ljl.javaweb.demo.jsp2taglib
                  |---- AddTag.java
    src/main/webapp
        |---- WEB-INF
                  |---- jsp2taglib
                            |---- demo.tld
        |---- demo/jsp2taglib
                  |---- add.jsp

    文件内容

    AddTag.java

    package cn.ljl.javaweb.demo.jsp2taglib;
    import java.io.IOException;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    /**
     * 用来演示带属性的标签.<br/>
     * 实现求和的功能.
     * @author lijinlong
     *
     */
    public class AddTag extends SimpleTagSupport {
        
        private int arg1;
        private int arg2;
        
        public int getArg1() {
            return arg1;
        }
        public void setArg1(int arg1) {
            this.arg1 = arg1;
        }
        public int getArg2() {
            return arg2;
        }
        public void setArg2(int arg2) {
            this.arg2 = arg2;
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            int result = arg1 + arg2;
            
            String template = "the result of arg1 + arg2 is:%s";
            String content = String.format(template, String.valueOf(result));
            
            JspWriter out = getJspContext().getOut();
            out.print(content);
        }
    }
    注意:需要将哪一个field作为标签的属性,就要为这个field添加对应的getter和setter。

    demo.tld

    这里只给出添加的内容。
        <tag>
            <description>实现求和的功能 - 用来演示带属性的标签</description>
            <name>add</name>
            <tag-class>cn.ljl.javaweb.demo.jsp2taglib.AddTag</tag-class>
            <body-content>empty</body-content>
            <attribute>
                <name>arg1</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>arg2</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
        </tag>
    attribute元素为标签添加属性,可以出现多次,每一次声明一个属性:
    • name
      属性的名称
    • required
      属性是否必需,true 或 false
    • fragment
      是否支持jsp脚本、表达式等动态内容,true 或 false

    add.jsp

    <%@ page language="java" contentType="text/html; charset=GBK"
        pageEncoding="GBK"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@ taglib uri="http://www.lijinlong.cn/demotaglib" prefix="demo"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    <title>自定义标签 - Add</title>
    </head>
    <body>
    <h2>求3+5的和:</h2>
    <demo:add arg1="3" arg2="5" />
    </body>
    </html>

    AddServlet.java

    package cn.ljl.javaweb.demo.jsp2taglib.servlet;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    @WebServlet(name = "addServlet", urlPatterns = { "/demo/jsp2taglib/add" })
    public class AddServlet extends HttpServlet {
        private static final long serialVersionUID = 3526679109725991549L;
        private static final String VIEW_ADD = "/demo/jsp2taglib/add.jsp";
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            req.getRequestDispatcher(VIEW_ADD).forward(req, resp);
        }
    }

    测试

    支持标签体的标签


    定义一个支持标签体的标签 -  iterator,它将对一个字符串列表进行迭代,每一次迭代都动态输出标签体的内容。

    文件目录结构

    src/main/java
        |---- cn.ljl.javaweb.demo.jsp2taglib.servlet
                  |---- IteratorServlet.java
        |---- cn.ljl.javaweb.demo.jsp2taglib
                  |---- IteratorTag.java
    src/main/webapp
        |---- WEB-INF
                  |---- jsp2taglib
                            |---- demo.tld
        |---- demo/jsp2taglib
                  |---- iterator.jsp

    文件内容

    IteratorTag.java

    package cn.ljl.javaweb.demo.jsp2taglib;
    import java.io.IOException;
    import java.util.List;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    /**
     * 实现迭代输出器的功能.<br>
     * 用来演示带有标签体的标签.
     * 
     * @author lijinlong
     * 
     */
    public class IteratorTag extends SimpleTagSupport {
        private List<String> collection;
        private String eleAttrName;
        public List<String> getCollection() {
            return collection;
        }
        public void setCollection(List<String> collection) {
            this.collection = collection;
        }
        public String getEleAttrName() {
            return eleAttrName;
        }
        public void setEleAttrName(String eleAttrName) {
            this.eleAttrName = eleAttrName;
        }
        @Override
        public void doTag() throws JspException, IOException {
            for (String ele : collection) {
                getJspContext().setAttribute(eleAttrName, ele);
                getJspBody().invoke(null);
            }
        }
    }
    注意:
    1. 在标签处理类中,可以通过getJsoContext()来设置/获取共享变量。
    2. 输出标签体的内容:getJspBody().invoke(null);

    demo.tld

    这里仅给出新增的内容:
        <tag>
            <description>迭代输出所有字符串</description>
            <name>iterator</name>
            <tag-class>cn.ljl.javaweb.demo.jsp2taglib.IteratorTag</tag-class>
            <body-content>scriptless</body-content>
            <attribute>
                <name>collection</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>eleAttrName</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
        </tag>
    注意:为了支持标签体,body-content要设置成scriptless。

    iterator.jsp

    <%@ page language="java" contentType="text/html; charset=GBK"
        pageEncoding="GBK"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@ taglib uri="http://www.lijinlong.cn/demotaglib" prefix="demo"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    <title>自定义标签 - iterator</title>
    </head>
    <body>
        <h2>我们给您的建议:</h2>
        <ol>
            <demo:iterator collection="${requestScope.adviceList}" eleAttrName="item">
                <li>${pageScope.item}</li>
            </demo:iterator>
        </ol>
    </body>
    </html>
    说明:
    1. 这里从request scope取得的adviceList是在Servlet中放进去的。
    2. iterator标签设计为,将集合中的每一个元素设置到page scope的属性中,其name由eleAttrName指定。
    3. 我们的jsp非常的简洁。

    IteratorServlet.java

    package cn.ljl.javaweb.demo.jsp2taglib.servlet;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    @WebServlet(name = "iteratorServlet", urlPatterns = { "/demo/jsp2taglib/iterator" })
    public class IteratorServlet extends HttpServlet {
        private static final long serialVersionUID = 4201830343915991973L;
        
        private static final String VIEW_SHOW = "/demo/jsp2taglib/iterator.jsp";
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            List<String> advices = new ArrayList<String>();
            advices.add("早睡早起。");
            advices.add("坚持锻炼身体。");
            advices.add("每天留半个小时发呆或者冥想。");
            advices.add("保持心情平和。");
            advices.add("专注认真但不要急功近利。");
            advices.add("赶紧脱单。");
            
            req.setAttribute("adviceList", advices);
            
            req.getRequestDispatcher(VIEW_SHOW).forward(req, resp);
        }
        
    }

    测试

    支持JspFragment的标签


    API javax.servlet.jsp.tagext.JspFragment
    • javax.servlet.jsp.JspContext getJspContext()
      返回绑定到当前JspFragment的JspContext
    • void invoke(java.io.Writer out)
      将当前的jsp片段输出到指定的writer。如果参数out为null,就输出到绑定的JspContext调用getOut()返回的,javax.servlet.jsp.JspWriter对象。
    另外,在支持标签体的标签-iterator中,我们曾这样输出标签体的内容:
    1. getJspBody().invoke(null);// getJspBody()返回的就是JspFragment的对象
     
    支持JspFragment的标签,就是支持JspFragment类型的属性的标签,而且可以定义多个这样的属性。另外,标签体可以视为一个隐藏的JspFragment属性。所以,只支持标签体的标签,只能获取一个JspFragment;支持JspFragment的标签,可以获取多个JspFragment。

    设计demo

    我们应该经历过一些讨论会、辩论会,抛出一个问题,试图获得一个被普遍认可的答案。或许有的问题是没有答案的,有的问题又不止一个答案。在这里我们简化其模型,将一些问题及其唯一的答案输出到页面——关键是“问题”和“答案”拥有不同的样式,所以我们需要为标签处理类添加两个JspFragment的属性;一个定义怎么输出“问题”,一个定义怎么输出“答案”。
    当然,这并不是一个很好的demo,因为使用只支持标签体的标签可以实现同样的功能;大家可以自行尝试改版。

    文件目录结构

    src/main/java
        |---- cn.ljl.javaweb.demo.jsp2taglib.domain
                  |---- Topic.java
        |---- cn.ljl.javaweb.demo.jsp2taglib.servlet
                  |---- TopicServlet.java
        |---- cn.ljl.javaweb.demo.jsp2taglib
                  |---- TopicTag.java
    src/main/webapp
        |---- WEB-INF
                  |---- jsp2taglib
                            |---- demo.tld
        |---- demo/jsp2taglib
                  |---- topic.jsp
    说明:这一次增加了一个domain(Topic.java),用来封装问题和答案。

    文件内容

    Topic.java

    package cn.ljl.javaweb.demo.jsp2taglib.domain;
    /**
     * 这是一个pojo,用于封装一个问题及其唯一的答案.
     * @author lijinlong
     *
     */
    public class Topic {
        private String question;
        private String answer;
        
        public Topic(String question, String answer) {
            super();
            this.question = question;
            this.answer = answer;
        }
        
        public String getQuestion() {
            return question;
        }
        public void setQuestion(String question) {
            this.question = question;
        }
        public String getAnswer() {
            return answer;
        }
        public void setAnswer(String answer) {
            this.answer = answer;
        }
    }

    TopicTag.java

    package cn.ljl.javaweb.demo.jsp2taglib;
    import java.io.IOException;
    import java.util.List;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    import cn.ljl.javaweb.demo.jsp2taglib.domain.Topic;
    /**
     * 用来演示支持JspFragment的标签.<br>
     * 这个标签将迭代一个话题的列表,允许jsp分别定义如何输出问题和答案.
     * @author lijinlong
     *
     */
    public class TopicTag extends SimpleTagSupport {
        /** 话题列表 */
        private List<Topic> topicList;
        /** 问题attribute的name */
        private String quesAttrName;
        /** 答案attribute的name */
        private String answAttrName;
        /** 问题的JspFragment */
        private JspFragment quesFrag;
        /** 答案的JspFragment */
        private JspFragment answFrag;
        public List<Topic> getTopicList() {
            return topicList;
        }
        public void setTopicList(List<Topic> topicList) {
            this.topicList = topicList;
        }
        public String getQuesAttrName() {
            return quesAttrName;
        }
        public void setQuesAttrName(String quesAttrName) {
            this.quesAttrName = quesAttrName;
        }
        public String getAnswAttrName() {
            return answAttrName;
        }
        public void setAnswAttrName(String answAttrName) {
            this.answAttrName = answAttrName;
        }
        public JspFragment getQuesFrag() {
            return quesFrag;
        }
        public void setQuesFrag(JspFragment quesFrag) {
            this.quesFrag = quesFrag;
        }
        public JspFragment getAnswFrag() {
            return answFrag;
        }
        public void setAnswFrag(JspFragment answFrag) {
            this.answFrag = answFrag;
        }
        @Override
        public void doTag() throws JspException, IOException {
            for (Topic t : topicList) {
                getJspContext().setAttribute(quesAttrName, t.getQuestion());
                getJspContext().setAttribute(answAttrName, t.getAnswer());
                quesFrag.invoke(null);
                answFrag.invoke(null);
            }
        }
    }

    demo.tld

        <tag>
            <description>输出话题</description>
            <name>topic</name>
            <tag-class>cn.ljl.javaweb.demo.jsp2taglib.TopicTag</tag-class>
            <body-content>empty</body-content>
            <attribute>
                <name>topicList</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>quesAttrName</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>answAttrName</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>quesFrag</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>answFrag</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
        </tag>
    注意:
    1. 这里的body-content要设置为empty
    2. 支持JspFragment的配置和支持属性的配置并没有什么区别,JspFragment也只是属性的类型罢了

    topic.jsp

    <%@ page language="java" contentType="text/html; charset=GBK"
        pageEncoding="GBK"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@ taglib uri="http://www.lijinlong.cn/demotaglib" prefix="demo"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    <title>自定义标签 - topic</title>
    </head>
    <body>
        <h2>我们讨论了下述的问题,并统一了其答案:</h2>
        <demo:topic topicList="${requestScope.topicList }" quesAttrName="ques"
            answAttrName="answ">
            <jsp:attribute name="quesFrag">
                <div style="font-weight: bold;">
                    ${pageScope.ques}
                </div>
            </jsp:attribute>
            <jsp:attribute name="answFrag">
                <div style="margin-top: 5px; margin-bottom: 15px;">
                    ${pageScope.answ}
                </div>
            </jsp:attribute>
        </demo:topic>
    </body>
    </html>
    说明:为JspFragment类型的属性赋值,要使用<jsp:attribute>标签。

    TopicServlet.java

    package cn.ljl.javaweb.demo.jsp2taglib.servlet;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import cn.ljl.javaweb.demo.jsp2taglib.domain.Topic;
    @WebServlet(name = "topicServlet", urlPatterns = { "/demo/jsp2taglib/topic" })
    public class TopicServlet extends HttpServlet {
        private static final long serialVersionUID = -2717086554249858215L;
        private static final String VIEW_SHOW = "/demo/jsp2taglib/topic.jsp";
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            List<Topic> topicList = new ArrayList<Topic>();
            topicList.add(new Topic("我很想做一件事,但是又害怕失败,怎么办?",
                    "害怕失败比失败本身更可怕。失败只是一时的,害怕失败却会纠缠你很久。"));
            topicList.add(new Topic("最近被一些人否定了,我觉得自己很没用。",
                    "别人轻视了你,是轻视你的过往;你轻视了自己,是放弃了你的未来。平静地对待,平静地加油。"));
            topicList.add(new Topic("我被一个同学骗了,再也不敢相信任何人了。",
                    "所有的人都靠谱,就没有欺骗;所有的人都不靠谱,就欺骗不了。就是有人不可信,才会有些人可信,你要学会鉴别,不要失望。"));
            req.setAttribute("topicList", topicList);
            req.getRequestDispatcher(VIEW_SHOW).forward(req, resp);
        }
    }

    测试

    总结

    有必要对这一块做个总结,因为它看起来要“复杂”一点。
    与支持属性的标签相比,在编写标签处理类、添加配置上都没有什么区别,只是在jsp中要使用<jsp:attribute>来为JspFragment类型的属性赋值。
    与支持标签体的标签相比,支持JspFragment看起来可以把标签体划分成多个部分,每一个部分作为标签处理类的一个属性。

    支持动态属性的标签


    支持动态属性,即支持不限定属性的个数和名称。

    文件目录结构

    src/main/java
        |---- cn.ljl.javaweb.demo.jsp2taglib.servlet
                  |---- DynaAttrServlet.java
        |---- cn.ljl.javaweb.demo.jsp2taglib
                  |---- DynamicAttributesTag.java
    src/main/webapp
        |---- WEB-INF
                  |---- jsp2taglib
                            |---- demo.tld
        |---- demo/jsp2taglib
                  |---- dynaAttr.jsp

    文件内容

    DynamicAttributesTag.java

    package cn.ljl.javaweb.demo.jsp2taglib;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.tagext.DynamicAttributes;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    /**
     * 动态属性标签库.<br>
     * 不限制属性的个数和属性的名称.<br>
     * @author lijinlong
     *
     */
    public class DynamicAttributesTag extends SimpleTagSupport implements
            DynamicAttributes {
        private List<String> keys = new ArrayList<String>();
        private List<Object> values = new ArrayList<Object>();
        
        @Override
        public void setDynamicAttribute(String uri, String localName, Object value)
                throws JspException {
            keys.add(localName);
            values.add(value);
        }
        
        @Override
        public void doTag() throws JspException, IOException {
            JspWriter out = getJspContext().getOut();
            out.println("<ol>");
            for (int i = 0; i < keys.size(); i ++) {
                String key = keys.get(i);
                Object value = values.get(i);
                out.println("<li>" + key + "=" + value + "</li>");
            }
            out.println("</ol>");
        }
    }
    说明:支持动态属性的标签处理类,需要实现javax.servlet.jsp.tagext.DynamicAttributes接口,实现setDynamicAttribute方法以存储动态属性。

    demo.tld

        <tag>
            <name>dynaAttr</name>
            <tag-class>cn.ljl.javaweb.demo.jsp2taglib.DynamicAttributesTag</tag-class>
            <body-content>empty</body-content>
            <dynamic-attributes>true</dynamic-attributes>
        </tag>
    注意:这里配置了dynamic-attributes来支持动态属性。

    dynaAttr.jsp

    <%@ page language="java" contentType="text/html; charset=GBK"
        pageEncoding="GBK"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@ taglib uri="http://www.lijinlong.cn/demotaglib" prefix="demo"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    <title>自定义标签 - dynaAttr</title>
    </head>
    <body>
    <h2>指定了三个属性:</h2>
    <demo:dynaAttr name="Adam" age="24" favorite="books" />
    </body>
    </html>
    说明:在使用标签时,属性的个数、名称都是自由的。

    DynaAttrServlet.java

    package cn.ljl.javaweb.demo.jsp2taglib.servlet;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    @WebServlet(name="dynaAttrServlet", urlPatterns={"/demo/jsp2taglib/dynaAttr"})
    public class DynaAttrServlet extends HttpServlet {
        private static final long serialVersionUID = -3146911293779890912L;
        
        private static final String VIEW_SHOW = "/demo/jsp2taglib/dynaAttr.jsp";
        
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            req.getRequestDispatcher(VIEW_SHOW).forward(req, resp);
        }
        
    }

    测试

    开源标签库


    • JSTL
      Sun提供的一套标签库
    • DisplayTag
      Apache组织下的一套开源标签库
  • 相关阅读:
    为什么说性别字段不适合做索引?
    过程数据的记录(事务问题)
    两个系统操作同一条表记录涉及的事务的坑(依护系统)
    mybatis插件自动生成代码报错。
    ORACLE使用plsql和其他工具进行表结构和数据迁移
    ORACLE获取建表SQL
    学习英语的技巧
    Oracle的用户管理
    Jmeter做压力测试
    强烈推荐(原创亲测)!!!Fiddler抓取https设置详解(图文)
  • 原文地址:https://www.cnblogs.com/ywjy/p/5228592.html
Copyright © 2011-2022 走看看