您的位置:首页 > Web前端 > JavaScript

Jsp中自定义标签

2016-09-13 11:15 302 查看

Jsp中自定义标签

Jsp中自定义标签
概述

需求

自定义标签实战

自定义标签的执行过程

自定义标签的作用

概述

很明显,内置标签和JSTL标签不能完全满足我们的开发需求,在实际的应用中我们经常会使用大量的自定义标签,本文将给出一个自定义标签的实例来说明整个过程。

需求

在Jsp中使用自定义标签实现:显示连接服务器的客户端的IP地址。当然我们可以在Jsp中使用脚本完成该任务,脚本如下:

<%
String ip = request.getRemoteHost();
out.write(ip);
%>


在一个新建的Jsp页面中写入上面的Java代码,便可以很轻松的实现需求,但是有两点不好的地方:

在Jsp中我们应该尽量少些Java代码

需求中要求使用标签实现该功能,但是上述方法使用的是Jsp的脚本,不符合要求

搜索了JSTL的标签库我们发现:不存在这样的标签使得这个需求能够很完美的实。那么是不是意味着没有办法实现了呢?不是,我们使用自定义标签,下面将使用该实例,实现一个自定义标签。

自定义标签实战

需要明确的是:每一个标签的背后实际上都是Java代码,所以我们自定义的标签理所当然应该有Java类的支持。下面将从头讲述实现自定义标签的方法。

书写一个Java类,将标签背后的实际处理逻辑写到该类中

package com.jpzhutech.tag;
import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
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.SimpleTagSupport;

public class ShowIp extends SimpleTagSupport{

//覆盖其中的doTag()方法
@Override
public void doTag() throws JspException, IOException {
//向浏览器输出客户的IP地址
PageContext pageContext = (PageContext)this.getJspContext();
HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
String ip = request.getRemoteHost();
JspWriter out = pageContext.getOut();
out.write("当前客户的IP地址是:"+ip);
}
}


在/WebRoot/WEB-INF/下写一个tld文件,该tld文件的写法可以参考JSTL核心标签库的语法,将自定义标签和上面的Java代码绑定在一起

<!--在WebRoot/WEB-INF中写一个tld文件,假设我命名为jpzhutech.tld-->
<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1">
<!-- 标签库的版本 -->
<tlib-version>1.1</tlib-version>
<!-- 标签库的访问前缀 -->
<short-name>jpzhutech</short-name>
<!-- tld文件的唯一标记 -->
<uri>http://www.jpzhutech.com</uri>

<tag>
<!-- 标签名称 -->
<name>ShowIp</name>
<!-- 标签处理器的完成类名 包名+类名 -->
<tag-class>com.jpzhutech.tag.ShowIp</tag-class>
<!-- 输出标签体的内容格式 -->
<body-content>scriptless</body-content>
</tag>
</taglib>


在Jsp中引入自定的标签

<%--index.jsp--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://www.jpzhutech.com"  prefix="jpzhutech"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>自定义标签</title>
</head>
<body>
<jpzhutech:ShowIp></jpzhutech:ShowIp>
</body>
</html>


自定义标签的执行过程

解释上述实例当访问http://localhost:8080/TagDefinition/index.jsp 究竟发生了什么呢?

访问http://localhost:8080/TagDefinition/index.jsp

tomcat服务器把Jsp文件翻译成为Java源文件,在编译成class文件,后执行类中的方法

接着检查Jsp文件的taglib指令,检查是否存在一个名字为http://www.jpzhutech.com 的tld文件

当读到Jsp文件的标签时,发现属于上述tld文件中的标签,会到该tld文件中找到相应的tag标签,并且该标签必须是唯一的,于是找到相应的tag-class

最后执行tag-class中的方法,输出想要的结果

自定义标签的作用

控制标签体内容是否输出

package com.jpzhutech.tag;

import java.io.IOException;

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.SimpleTagSupport;

public class DemoTag extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
PageContext context =(PageContext) getJspContext();

//控制标签体的内容是否输出
JspFragment jspBody = this.getJspBody();  //得到标签体的内容

//执行invoke方法会将标签体内容输出到一个Writer对象中
JspWriter out = context.getOut();
jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出

}
}


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://www.jpzhutech.com"  prefix="jpzhutech"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>自定义标签</title>
</head>

<body>
<jpzhutech:ShowIp>你好</jpzhutech:ShowIp>
<jpzhutech:demotag>标签体的内容</jpzhutech:demotag>
标签余下的内容
</body>
</html>


<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1">
<!-- 标签库的版本 -->
<tlib-version>1.1</tlib-version>
<!-- 标签库的访问前缀 -->
<short-name>jpzhutech</short-name>
<!-- tld文件的唯一标记 -->
<uri>http://www.jpzhutech.com</uri>

<tag>
<!-- 标签名称 -->
<name>ShowIp</name>
<!-- 标签处理器的完成类名 包名+类名 -->
<tag-class>com.jpzhutech.tag.ShowIp</tag-class>
<!-- 输出标签体的内容格式 -->
<body-content>scriptless</body-content>
</tag>

<tag>
<!-- 标签名称 -->
<name>demotag</name>
<!-- 标签处理器的完成类名 包名+类名 -->
<tag-class>com.jpzhutech.tag.DemoTag</tag-class>
<!-- 输出标签体的内容格式 -->
<body-content>scriptless</body-content>
</tag>
</taglib>


控制标签余下的内容是否输出

package com.jpzhutech.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class DemoTag extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
PageContext context =(PageContext) getJspContext();

//功能一:控制标签体的内容是否输出
JspFragment jspBody = this.getJspBody();  //得到标签体的内容

//执行invoke方法会将标签体内容输出到一个Writer对象中
JspWriter out = context.getOut();
jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出

//功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出
throw new SkipPageException();
}
}


控制重复输出标签体的内容

package com.jpzhutech.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class DemoTag extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
PageContext context =(PageContext) getJspContext();

//功能一:控制标签体的内容是否输出
JspFragment jspBody = this.getJspBody();  //得到标签体的内容

//执行invoke方法会将标签体内容输出到一个Writer对象中
JspWriter out = context.getOut();
jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出

// 功能三:控制重复输出标签体的内容
for (int i = 1; i <= 5; i++) {
jspBody.invoke(out);
}

//功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出
throw new SkipPageException();

}
}


改变标签体的内容

package com.jpzhutech.tag;

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

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class DemoTag extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
PageContext context =(PageContext) getJspContext();

//功能一:控制标签体的内容是否输出
JspFragment jspBody = this.getJspBody();  //得到标签体的内容

//执行invoke方法会将标签体内容输出到一个Writer对象中
JspWriter out = context.getOut();
jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出

// 功能三:控制重复输出标签体的内容
for (int i = 1; i <= 5; i++) {
jspBody.invoke(out);
}

//功能四:改变标签体的内容
StringWriter writer = new StringWriter();
jspBody.invoke(writer);
String string = writer.toString();   //将要输出的内容转换成字符串
//改变其内容
String lowerCase = string.toLowerCase();  //将字符串转换为小写

out.write(lowerCase);  //使用out对象手动输出,已经不能使用jspBody.invoke(out)方法来输出

//功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出
throw new SkipPageException();

}
}


带属性的标签

注意:输出带属性的标签必须在定义每一个属性时,同时加上get和set方法,像下面的例子

package com.jpzhutech.tag;

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

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class DemoTag extends SimpleTagSupport {
private String name;
private String price;
private String store;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPrice() {
return price;
}

public void setPrice(String price) {
this.price = price;
}

public String getStore() {
return store;
}

public void setStore(String store) {
this.store = store;
}

@Override
public void doTag() throws JspException, IOException {
PageContext context =(PageContext) getJspContext();

//功能一:控制标签体的内容是否输出
JspFragment jspBody = this.getJspBody();  //得到标签体的内容

//执行invoke方法会将标签体内容输出到一个Writer对象中
JspWriter out = context.getOut();
jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出

// 功能三:控制重复输出标签体的内容
for (int i = 1; i <= 5; i++) {
jspBody.invoke(out);
}

//功能四:改变标签体的内容
StringWriter writer = new StringWriter();
jspBody.invoke(writer);
String string = writer.toString();   //将要输出的内容转换成字符串
//改变其内容
String lowerCase = string.toLowerCase();  //将字符串转换为小写

out.write(lowerCase);  //使用out对象手动输出,已经不能使用jspBody.invoke(out)方法来输出

//输出带属性的标签
out.write("书名:"+name);
out.write("价格:"+price);
out.write("书店:"+store);
//功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出
throw new SkipPageException();

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jsp 标签