0.前言
这个自定义标签非常有意思,其实学到这里,已经逐渐开始接触较为底层的源码了。平时我们在html、xml或者jsp里面,使用带有尖括号的标签时,就已经感受到其便捷性和美观性,非常适合新手入门使用。
但是这些标签是如何被定义,如何达到使用的目的呢?如此之多的Web框架不断涌现的如今,这些优秀的框架是如何被制造的呢?其实这些便捷性,追根究底,在自主定义标签之中可见一斑。
1.要求1
1.1自主定义一个标签,使用后可以在jsp页面上显示出学生的信息。
2.1 显示特定性别的学生信息
3.1 显示默认性别为“男”,特定年龄的学生信息
2.实现
标签的实现,底层其实是利用java文件做的,所以需要先建立一个类,名字随便,这里既然要显示全部学生的信息,那么不妨叫做DisplayAllTags.java,包名叫做tags。
2.1 标签类
DisplayAllTags.java:
package tags;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import Bean.Student;
import Dao.StudentDao;
//显示所有学生的资料
//1.对于空体标签,需要继承javax.servlet.jsp.tagext.TagSupport;
//2.重写doStartTag(),doEndTag()
public class DisplayAllTag extends TagSupport{
@Override
public int doStartTag() throws JspException {
System.out.println("doStartTag");
return this.SKIP_BODY;
}
@Override
public int doEndTag() throws JspException {
System.out.println("doEndTag");
StudentDao studentDao=new StudentDao();
ArrayList stus=studentDao.getAllInfo();
JspWriter out=this.pageContext.getOut();
try {
out.println("<table bgColor=yellow>");
out.println("<tr>");
out.println("<td>学号</td>");
out.println("<td>姓名</td>");
out.println("<td>性别</td>");
out.println("<td>年龄</td>");
out.println("</tr>");
for(int i=0;i<stus.size();i++)
{
Student stu=(Student)stus.get(i);
out.println("<tr>");
out.println("<td>"+stu.getAccount()+"</td>");
out.println("<td>"+stu.getName()+"</td>");
out.println("<td>"+stu.getSex()+"</td>");
out.println("<td>"+stu.getAge()+"</td>");
out.println("</tr>");
}
out.println("</table>");
} catch (IOException e) {
e.printStackTrace();
}
return this.EVAL_PAGE;
}
}
在上述代码中,因为显示全部学生的标签只需要标签+标签名即可,不需要其他的,所以是一个空体标签,自定义空体标签需要重写两个方法,一个是doStartTag,一个是doEndTag。整个java类需要继承自TagSupport。
为了更加明显的看出标签的使用过程,当方法被触发的时候,控制台会打印出该方法的名字。doStartTag是运行时触发的方法,实际内容是放在doEndTag中。
在doEndTag中,先从数据库获取学生的全部信息,存入ArrayList,调用jsp的API,使得数据可以打印在jsp页面,因为要用到ArrayList的第i个的第X个属性,所以要用两次ArrayList,用for循环,通过get(i)的方式,从ArrayList里面不断的取出数据,打印在jsp页面上。
2.2 注册标签
标签类写好了,那么系统要怎么认识这个标签呢,我们平时使用的XXX.tld,都是现成的,现在我们需要自己写一个.tld文件了,名字随意,就叫做stu.tld吧。
stu.tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib> <!--标签库定义文件根结点:taglib -->
<tlibversion>1.2</tlibversion> <!-- 标签库版本 -->
<jspversion>1.1</jspversion> <!-- JSP版本 -->
<shortname>stu</shortname> <!-- 标签库名称 -->
<uri>stu</uri> <!-- 外界导入标签库时认识的名称 -->
<!-- 定义标签 -->
<tag>
<name>displayAll</name>
<tagclass>tags.DisplayAllTag</tagclass>
</tag>
</taglib>
2.3 使用标签
然后在jsp页面调用这个标签就可以了。
display.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="stu" prefix="stu" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<stu:displayAll></stu:displayAll>
</body>
</html>
因为在这个jsp页面的开头,我们引入自定义的标签stu,前缀定义为:stu,前缀的定义是随意的,只要你喜欢,叫做abc也可以。
<stu:displayAll></stu:displayAll>
就可以轻松的把数据库里面的所有学生信息都显示出来。
2.4 演示标签
3.实现2
3.1 标签类
DisplayBySexTag.java:
package tags;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import Bean.Student;
import Dao.StudentDao;
/**
* 作用:
*@author 欧世乐
*/
//通过性别属性显示学生,建议一个JavaBean风格的属性
public class DisplayBySexTag extends TagSupport{
private String sex;
/**
* @return the sex
*/
public String getSex() {
return sex;
}
/**
* @param sex the sex to set
*/
public void setSex(String sex) {
this.sex = sex;
}
@Override
public int doStartTag() throws JspException {
System.out.println("doStartTag");
return this.SKIP_BODY;
}
@Override
public int doEndTag() throws JspException {
System.out.println("doEndTag");
StudentDao studentDao=new StudentDao();
ArrayList stus=studentDao.queryBySex(sex);
JspWriter out=this.pageContext.getOut();
try {
out.println("<table bgColor=yellow>");
out.println("<tr>");
out.println("<td>学号</td>");
out.println("<td>姓名</td>");
out.println("<td>性别</td>");
out.println("<td>年龄</td>");
out.println("</tr>");
for(int i=0;i<stus.size();i++)
{
Student stu=(Student)stus.get(i);
out.println("<tr>");
out.println("<td>"+stu.getAccount()+"</td>");
out.println("<td>"+stu.getName()+"</td>");
out.println("<td>"+stu.getSex()+"</td>");
out.println("<td>"+stu.getAge()+"</td>");
out.println("</tr>");
}
out.println("</table>");
} catch (IOException e) {
e.printStackTrace();
}
return this.EVAL_PAGE;
}
}
上述代码和前一个标签类大同小异,只是从DAO获取的方式略有不同。因为这里建立的java是JavaBean风格的,所以sex应该给予setter和getter风格。
3.2 注册标签
<tag>
<name>displayBySex</name>
<tagclass>tags.DisplayBySexTag</tagclass>
<attribute> <!-- 注册属性 -->
<name>sex</name>
<required>true</required> <!-- 是否必须 -->
</attribute>
</tag>
因为这里要根据性别来指定学生信息,所以标签里面需要带上属性值attribute
3.3 使用标签
<stu:displayBySex sex="女"></stu:displayBySex>
3.3 演示标签
这里学号是null是因为我的数据库没有这个属性,自己添加上就可以了。
4.实现3
4.1 标签类
DisplayBySATag.java:
package tags;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import Bean.Student;
import Dao.StudentDao;
/**
* 作用:
*@author 欧世乐
*/
public class DisplayBySATag extends TagSupport{
private String sex="男",age;
/**
* @return the sex
*/
public String getSex() {
return sex;
}
/**
* @param sex the sex to set
*/
public void setSex(String sex) {
this.sex = sex;
}
/**
* @return the age
*/
public String getAge() {
return age;
}
/**
* @param add the age to set
*/
public void setAge(String age) {
this.age = age;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return this.SKIP_BODY;
}
@Override
public int doEndTag() throws JspException {
StudentDao studentDao=new StudentDao();
ArrayList stus=studentDao.queryBySA(sex,age);
JspWriter out=this.pageContext.getOut();
try {
out.println("<table bgColor=yellow>");
out.println("<tr>");
out.println("<td>学号</td>");
out.println("<td>姓名</td>");
out.println("<td>性别</td>");
out.println("<td>年龄</td>");
out.println("</tr>");
for(int i=0;i<stus.size();i++)
{
Student stu=(Student)stus.get(i);
out.println("<tr>");
out.println("<td>"+stu.getAccount()+"</td>");
out.println("<td>"+stu.getName()+"</td>");
out.println("<td>"+stu.getSex()+"</td>");
out.println("<td>"+stu.getAge()+"</td>");
out.println("</tr>");
}
out.println("</table>");
} catch (IOException e) {
e.printStackTrace();
}
return this.EVAL_PAGE;
}
}
4.2 注册标签
<tag>
<name>displayBySA</name>
<tagclass>tags.DisplayBySATag</tagclass>
<attribute> <!-- 注册属性 -->
<name>sex</name>
<required>false</required> <!-- 是否必须 -->
</attribute>
<attribute>
<name>age</name>
<required>true</required>
</attribute>
</tag>
上面的DisplayBySATag.java中,默认给了sex“男",所以他不是必须的属性值。
4.3 使用标签
<stu:displayBySA age="7"></stu:displayBySA>
根据自己喜好,设置年龄
4.3 标签演示
5.小结
自定义标签非常的简单,根据实际需求定义标签,对开发环节有着巨大的裨益,真正意义上的体现了“开发者”的精神。