欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JSP自定义标签

程序员文章站 2022-03-04 11:59:08
...

mvvm框架盛行的今天jsp视乎已经out了,但是由于历史原因jsp使用范围依旧十分广泛。(本人 喜欢jsp ,在标签开发的效率上,jsp要比vue低很多,并且前后端分离的开发模式,在调试,部署,分工都要好很多。) 

第一步 : jsp标签的描述,声明

jsp标签需要使用xml描述(这里的文件格式是tld,依旧认为这就是xml)

<?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>jsp Label</description>
    <!-- 版本 -->
    <tlib-version>1.0</tlib-version>
    <!-- 短名 -->
    <short-name>kgo</short-name>
    <!-- 指定标签库URI -->
    <uri>/WEB-INF/JSPLabel.tld</uri>
     <!--   布局标签   -->
    <tag>
        <description>Layout</description>
        <!-- 标签库名字 -->
        <name>Layout</name>
        <!-- 标签处理类 -->
        <tag-class>com.telchina.label.ContainerLabel</tag-class>
        <!-- 标签体内容 -->
        <body-content>scriptless</body-content>
        <!-- 标签属性:driver -->
        <attribute>
            <name>layHeight</name>
            <required>false</required>
            <fragment>true</fragment>
        </attribute>
         <attribute>
            <name>layClass</name>
            <required>true</required>
            <fragment>true</fragment>
        </attribute>
    </tag>   
    <!--   卡片标签  -->
    <tag>
        <description>jsp卡片</description>
        <!-- 标签库名字 -->
        <name>Card</name>
        <!-- 标签处理类 -->
        <tag-class>com.telchina.label.CardLabel</tag-class>
        <!-- 标签体内容 -->
        <body-content>scriptless</body-content>
        <!-- 标签属性:driver -->
        <attribute>
            <name>title</name>
            <required>true</required>
            <fragment>true</fragment>
        </attribute>
    </tag>
     <!--   卡片标签  -->
    <tag>
        <description>jsp轮播</description>
        <!-- 标签库名字 -->
        <name>carousel</name>
        <!-- 标签处理类 -->
        <tag-class>com.telchina.label.CarouselLabel</tag-class>
        <!-- 标签体内容 -->
        <body-content>scriptless</body-content>
        <!-- 标签属性 -->
        <attribute>
            <name>id</name>
            <required>true</required>
            <fragment>true</fragment>
        </attribute>
    </tag>
    
</taglib>

这里讲一下几个重要的属性:

1)body-content 有如下四个属性 

tagdependent:标签体内容直接被写入BodyContent,由自定义标签类来进行处理,而不被JSP容器解释,

如下:

<test:myList>

select name,age from users

</test:myList>

JSP:接受所有JSP语法,如定制的或内部的tag、scripts、静态HTML、脚本元素、JSP指令和动作。如:

<my:test>

    <%=request.getProtocol()%>     

</my:test>

具体可参考后面附源码。

empty:空标记,即起始标记和结束标记之间没有内容。

下面几种写法都是有效的,

<test:mytag />

<test:mytag uname="Tom" />

<test:mytag></test:mytag>

scriptless:接受文本、EL和JSP动作。如上述使用<body-content> scriptless </body-content>则报错,具体可参考后面附源码。

注意:scriptless声明后标签内部不能为空。

2)required 参数是否必须 

第二步:书写jsp标签的实现类 

已上诉jsp标签中的Card标签为例

package com.kgo.label;

import java.io.IOException;
import java.io.StringWriter;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class CardLabel extends SimpleTagSupport {
	private StringBuffer head_buffer = new StringBuffer();
	private StringBuffer foot_buffer = new StringBuffer();
	// 属性
	private String title = "jsp卡片标签";

	private StringWriter sw = new StringWriter();

	public void doTag() throws JspException, IOException {
		JspWriter out = getJspContext().getOut();
		printHead();
		out.println(head_buffer.toString());

		getJspBody().invoke(sw);
		getJspContext().getOut().println(sw.toString());
		printFoot();
		out.println(foot_buffer.toString());
	}

	private void printHead() {
		head_buffer.append(String.format("<div class=\"%s %s\">%n", "layui-card", "kgo-card"));
		head_buffer.append(String.format("	<div class=\"%s\">%s</div>", "layui-card-header", title));
		head_buffer.append(String.format("	<div class=\"%s %s\">%n", "layui-card-body", "kgo-card-body"));
	}

	private void printFoot() {
		foot_buffer.append(String.format("	</div>%n"));
		foot_buffer.append(String.format("</div>%n"));
		foot_buffer.append(String.format("<script>"));
		foot_buffer.append(String.format("layui.use(['element','jquery'], function(){%n"));
		foot_buffer.append(String.format(" 	 var element = layui.element; %n"));
		foot_buffer.append(String.format(" 	 var $ = layui.jquery;%n  "));

		foot_buffer.append(String.format(" });%n"));
		foot_buffer.append(String.format("</script>"));
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

}

 

实现基本是这样:

属性  在tld里进行声明,在实现类中声明同名(必须同名)的私有变量,并添加set和get方法。

入口 我这里继承了SimpleTagSupport对象(jsp2.0以及以上版本才能使用该对象)入好函数则为 doTag() 方法。

打印 开始dom

JspWriter out = getJspContext().getOut();
out.println(head_buffer.toString());

这个标签可以嵌套其他标记进行使用,因此这里打印的是上半部分dom 

private void printHead() {
		head_buffer.append(String.format("<div class=\"%s %s\">%n", "layui-card", "kgo-card"));
		head_buffer.append(String.format("	<div class=\"%s\">%s</div>", "layui-card-header", title));
		head_buffer.append(String.format("	<div class=\"%s %s\">%n", "layui-card-body", "kgo-card-body"));
	}

这里是在封装layui标签,使用了一下字符串格式化,但是由于时间太匆忙未进行完善的封装 

唤醒嵌入的dom(可以不是dom,可以是文本,其他jsp标签都可以)

		getJspBody().invoke(sw);
		getJspContext().getOut().println(sw.toString());

这里就是打印嵌入在标签内部的dom结构。

打印 结束dom

printFoot();
		out.println(foot_buffer.toString());

打印的dom结构如下:

private void printFoot() {
		foot_buffer.append(String.format("	</div>%n"));
		foot_buffer.append(String.format("</div>%n"));
		foot_buffer.append(String.format("<script>"));
		foot_buffer.append(String.format("layui.use(['element','jquery'], function(){%n"));
		foot_buffer.append(String.format(" 	 var element = layui.element; %n"));
		foot_buffer.append(String.format(" 	 var $ = layui.jquery;%n  "));

		foot_buffer.append(String.format(" });%n"));
		foot_buffer.append(String.format("</script>"));
	}

第三步:webXML声明 

<jsp-config>
	<taglib>
	        <taglib-uri>/WEB-INF/JSPLabel.tld</taglib-uri>
	        <taglib-location>/WEB-INF/JSPLabel.tld</taglib-location>
	</taglib>
</jsp-config>

 

 

tld标签可以被打包进jar包,jstl标签就是这样的,这里我还没有做,日后补充。

 

相关标签: jsp 自定义标签