JSP自定义标签

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标签就是这样的,这里我还没有做,日后补充。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

keep-go-on

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值