java自定义标签



java自定义标签。

案例

问题的提出:现在要显示所有员工的资料,提出解决方案

传统方法:1. 在JSP里面写JDBC查询;2. 在JavaBean中写JDBC查询,在JSP中使用查询结果。

新的方法:能否使用一个标签(类似于html标签)嵌入到JSP文件中,让它自动显示这些信息?

答案:能。技术基础:XML。

标签种类

1. 空标签,没有属性,也没有体

例:<html:submit/>

2. 空体标签,有属性,没有体

<bean:write name=”student”/>

3. 有属性有体标签

<logic:iterate id=”book” name=”books”>

<bean:write name=”book”/>

</logic:iterate>

自定义标签的要素

1. 标签处理程序(一个java文件,已经被编译):使用不同的方法与对象来定义标签的行为i,即认识某属性的不同值能做不同的事情。

2. 标签库描述符(TLD)文件(一个XML格式文件):包含客户标签的描述性列表的XML文件,即识别不同的属性能做不同的事情。

3. JSP文件(为了嵌入自定义的标签):包含标签以及表示内容的HTML代码。

标签处理程序(一个java文件)

作用:包含类和方法的定义,定义标签的功能

对于空体标签,需要继承:javax.servlet.jsp.tagext.TagSupport

对于有体标签,需要继承:javax.servlet.jsp.tagext.BodyTagSupport

以上两个类都实现:Javax.servlet.jsp.tagext.Tag接口

Tag接口中的方法:

doStartTag():初始化标签的一些内容,如连数据库

doEndTag():作一些善后工作,如关数据库

release():释放这个标签对象

doAfterBody():完成标签体求值之后的调用


doBeforeBody():开始标签体求值之前调用

一般,无体标签doStartTag()返回SKIP_BODY,让标签不要对体求值,doEndTag()返回EVAL_PAGE,让标签后面的JSP继续执行;有体标签doStartTag()返回EVAL_BODY_TAG,让标签对体求值,doEndTag()返回EVAL_PAGE,让标签后面的JSP继续执行;对于标签里面的属性,类似于JavaBean中给它们编写get和set方法。

一般情况下的标签处理程序包含以下函数:

构造函数:用于进行这个标签解释时的初始化,如连接数据库

doStartTag():返回对这个标签的处理方法

doEndTag():做一些善后工作,如数据输出,关闭数据库等各种属性的get,set函数

最厉害的角色:pageContext保护成员。

标签库描述符(TLD)文件(一个XML文件)

TLD文件:为包含标签库描述的xml文件;包含库中所有客户标签的列表与描述。

实现空标签

新建MyTag项目,编写标签程序处理类DisplayAllTag,代码如下

[java] view plaincopyprint?01.package wang.tags; 02.import java.io.IOException; 03.import java.util.ArrayList; 04.import javax.servlet.jsp.JspException; 05.import javax.servlet.jsp.JspWriter; 06.import javax.servlet.jsp.tagext.TagSupport; 07.import wang.dao.EmployeeDao; 08.import wang.po.Employee; 09.// 显示所有员工的资料 10.public class DisplayAllTag extends TagSupport { 11. public DisplayAllTag() { 12. System.out.println(“DisplayAllTag构造函数”); 13. } 14. 15. public int doStartTag() throws JspException { 16. // 系统开始运行这个标签时自动调用 17. System.out.println(“doStartTag”); 18. return this.SKIP_BODY; //空体标签,不要对体求值 19. } 20. 21. public int doEndTag() throws JspException { 22. // 系统结束运行这个标签时自动调用 23. System.out.println(“doEndTag”); 24. EmployeeDao employeeDao = new EmployeeDao(); 25. ArrayList<Employee> employees = employeeDao.queryEmployees(); 26. //显示为表格 27. JspWriter out = pageContext.getOut(); 28. try { 29. out.print(“<table>”); 30. out.print(“<tr>”); 31. out.print(“<td>ID</td>”); 32. out.print(“<td>Name</td>”); 33. out.print(“<td>Email</td>”); 34. out.print(“<td>Birthday</td>”); 35. out.print(“<td>JobID</td>”); 36. out.print(“</tr>”); 37. for(Employee employee:employees){ 38. out.print(“<tr>”); 39. out.print(“<td>”+employee.getEmployeeId()+”</td>”); 40. out.print(“<td>”+employee.getFirstName()+” “+employee.getLastName()+”</td>”); 41. out.print(“<td>”+employee.getEmail()+”</td>”); 42. out.print(“<td>”+employee.getHireDate()+”</td>”); 43. out.print(“<td>”+ employee.getJboId()+”</td>”); 44. out.print(“</tr>”); 45. } 46. out.print(“</table>”); 47. } catch (IOException e) { 48. e.printStackTrace(); 49. } 50. return this.EVAL_PAGE; //让标签后面的JSP继续执行 51. } 52.} package wang.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 wang.dao.EmployeeDao;
import wang.po.Employee;
// 显示所有员工的资料
public class DisplayAllTag extends TagSupport {
public DisplayAllTag() {
System.out.println(“DisplayAllTag构造函数”);
}

public int doStartTag() throws JspException {
// 系统开始运行这个标签时自动调用
System.out.println(“doStartTag”);
return this.SKIP_BODY; //空体标签,不要对体求值
}

public int doEndTag() throws JspException {
// 系统结束运行这个标签时自动调用
System.out.println(“doEndTag”);
EmployeeDao employeeDao = new EmployeeDao();
ArrayList<Employee> employees = employeeDao.queryEmployees();
//显示为表格
JspWriter out = pageContext.getOut();
try {
out.print(“<table>”);
out.print(“<tr>”);
out.print(“<td>ID</td>”);
out.print(“<td>Name</td>”);
out.print(“<td>Email</td>”);
out.print(“<td>Birthday</td>”);
out.print(“<td>JobID</td>”);
out.print(“</tr>”);
for(Employee employee:employees){
out.print(“<tr>”);
out.print(“<td>”+employee.getEmployeeId()+”</td>”);
out.print(“<td>”+employee.getFirstName()+” “+employee.getLastName()+”</td>”);
out.print(“<td>”+employee.getEmail()+”</td>”);
out.print(“<td>”+employee.getHireDate()+”</td>”);
out.print(“<td>”+ employee.getJboId()+”</td>”);
out.print(“</tr>”);
}
out.print(“</table>”);
} catch (IOException e) {
e.printStackTrace();
}
return this.EVAL_PAGE; //让标签后面的JSP继续执行
}
}
编写EmployeeDao类,代码如下

[java] view plaincopyprint?01.package wang.dao; 02.import java.sql.Connection; 03.import java.sql.DriverManager; 04.import java.sql.ResultSet; 05.import java.sql.SQLException; 06.import java.util.ArrayList; 07.import wang.po.Employee; 08.public class EmployeeDao { 09. private Connection conn = null; 10. 11. public void initialConnection() { 12. try { 13. Class.forName(“oracle.jdbc.driver.OracleDriver”).newInstance(); 14. String url=”jdbc:oracle:thin:@localhost:1521:xe”; 15. conn = DriverManager.getConnection(url, “hr”, “hr”); 16. } catch (Exception e) { 17. e.printStackTrace(); 18. } 19. } 20. 21. public ArrayList<Employee> queryEmployees() { 22. ArrayList<Employee> employees = new ArrayList<Employee>(); 23. String sql = “select * from employees”; 24. try { 25. this.initialConnection(); 26. ResultSet rs = conn.createStatement().executeQuery(sql); 27. while(rs.next()) { 28. Employee employee = new Employee(); 29. employee.setEmployeeId(rs.getString(“EMPLOYEE_ID”)); 30. employee.setFirstName(rs.getString(“FIRST_NAME”)); 31. employee.setLastName(rs.getString(“LAST_NAME”)); 32. employee.setEmail(rs.getString(“EMAIL”)); 33. employee.setHireDate(rs.getString(“HIRE_DATE”)); 34. employee.setJboId(rs.getString(“JOB_ID”)); 35. employees.add(employee); 36. } 37. } catch (SQLException e) { 38. e.printStackTrace(); 39. } finally { 40. this.closeConnection(); 41. } 42. return employees; 43. } 44. 45. public void closeConnection() { 46. try { 47. if(conn!=null) { 48. conn.close(); 49. conn = null; 50. } 51. } catch (SQLException e) { 52. e.printStackTrace(); 53. } 54. } 55.} package wang.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import wang.po.Employee;
public class EmployeeDao {
private Connection conn = null;

public void initialConnection() {
try {
Class.forName(“oracle.jdbc.driver.OracleDriver”).newInstance();
String url=”jdbc:oracle:thin:@localhost:1521:xe”;
conn = DriverManager.getConnection(url, “hr”, “hr”);
} catch (Exception e) {
e.printStackTrace();
}
}

public ArrayList<Employee> queryEmployees() {
ArrayList<Employee> employees = new ArrayList<Employee>();
String sql = “select * from employees”;
try {
this.initialConnection();
ResultSet rs = conn.createStatement().executeQuery(sql);
while(rs.next()) {
Employee employee = new Employee();
employee.setEmployeeId(rs.getString(“EMPLOYEE_ID”));
employee.setFirstName(rs.getString(“FIRST_NAME”));
employee.setLastName(rs.getString(“LAST_NAME”));
employee.setEmail(rs.getString(“EMAIL”));
employee.setHireDate(rs.getString(“HIRE_DATE”));
employee.setJboId(rs.getString(“JOB_ID”));
employees.add(employee);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closeConnection();
}
return employees;
}

public void closeConnection() {
try {
if(conn!=null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
编写Employee类,代码如下

[java] view plaincopyprint?01.public class Employee { 02. private String employeeId; 03. private String firstName; 04. private String lastName; 05. private String email; 06. private String hireDate; 07. private String jboId; 08. 09. public String getEmployeeId() { 10. return employeeId; 11. } 12. public void setEmployeeId(String employeeId) { 13. this.employeeId = employeeId; 14. } 15. public String getFirstName() { 16. return firstName; 17. } 18. public void setFirstName(String firstName) { 19. this.firstName = firstName; 20. } 21. public String getLastName() { 22. return lastName; 23. } 24. public void setLastName(String lastName) { 25. this.lastName = lastName; 26. } 27. public String getEmail() { 28. return email; 29. } 30. public void setEmail(String email) { 31. this.email = email; 32. } 33. public String getHireDate() { 34. return hireDate; 35. } 36. public void setHireDate(String hireDate) { 37. this.hireDate = hireDate; 38. } 39. public String getJboId() { 40. return jboId; 41. } 42. public void setJboId (String jboId) { 43. this.jboId = jboId; 44. } 45.} public class Employee {
private String employeeId;
private String firstName;
private String lastName;
private String email;
private String hireDate;
private String jboId;

public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getHireDate() {
return hireDate;
}
public void setHireDate(String hireDate) {
this.hireDate = hireDate;
}
public String getJboId() {
return jboId;
}
public void setJboId (String jboId) {
this.jboId = jboId;
}
}
编写emp.tld文件,一般是放在WEB-INF目录下面,系统自动识别到,代码如下
[xhtml] view plaincopyprint?
01.<?xml version=”1.0″ encoding=”UTF-8″?>
02.<taglib> <!– 标签库定义文件根节点:taglib –>
03. <tlibversion>1.2</tlibversion> <!– 标签库版本 –>
04. <jspversion>1.1</jspversion> <!– Jsp版本 –>
05. <shortname>emp</shortname> <!– 标签库名称 –>
06. <uri>http://wang.mytag.emp</uri> <!– 外界导入标签库认识时的名称 –>
07. <!– 定义标签 –>
08. <tag>
09. <name>displayAll</name>
10. <tagclass>wang.tags.DisplayAllTag</tagclass>
11. </tag>
12.</taglib>
<?xml version=”1.0″ encoding=”UTF-8″?>
<taglib> <!– 标签库定义文件根节点:taglib –>
<tlibversion>1.2</tlibversion> <!– 标签库版本 –>
<jspversion>1.1</jspversion> <!– Jsp版本 –>
<shortname>emp</shortname> <!– 标签库名称 –>
<uri>http://wang.mytag.emp</uri> <!– 外界导入标签库认识时的名称 –>
<!– 定义标签 –>
<tag>
<name>displayAll</name>
<tagclass>wang.tags.DisplayAllTag</tagclass>
</tag>
</taglib>
编写displayAll.jsp文件,代码如下

[xhtml] view plaincopyprint?
01.<%@ page language=”java” import=”java.util.*” pageEncoding=”ISO-8859-1″%>
02.<%@ taglib uri=”http://wang.mytag.emp” prefix=”emp”%>
03.<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
04.<html>
05. <head>
06. <title>My JSP ‘displayAll.jsp’ starting page</title>
07. </head>
08. <body>
09. <emp:displayAll></emp:displayAll>
10. </body>
11.</html>
<%@ page language=”java” import=”java.util.*” pageEncoding=”ISO-8859-1″%>
<%@ taglib uri=”http://wang.mytag.emp” prefix=”emp”%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>My JSP ‘displayAll.jsp’ starting page</title>
</head>
<body>
<emp:displayAll></emp:displayAll>
</body>
</html>
部署项目,启动服务器,运行页面,得到正确的结果。

实现空体标签(不显示所有员工,比如按部门显示)

编写标签程序处理类DisplayByJobIDTag,代码如下

[java] view plaincopyprint?
01.package wang.tags;
02.import java.io.IOException;
03.import java.util.ArrayList;
04.import javax.servlet.jsp.JspException;
05.import javax.servlet.jsp.JspWriter;
06.import javax.servlet.jsp.tagext.TagSupport;
07.import wang.dao.EmployeeDao;
08.import wang.po.Employee;
09.//通过性别属性来显示
10.public class DisplayByJobIDTag extends TagSupport {
11. private String jobID;
12. public DisplayByJobIDTag() {
13. System.out.println(“DisplayAllTag构造函数”);
14. }
15. public int doStartTag() throws JspException {
16. // 系统开始运行这个标签时自动调用
17. System.out.println(“doStartTag”);
18. return this.SKIP_BODY; //空体标签,不要对体求值
19. }
20.
21. public int doEndTag() throws JspException {
22. // 系统结束运行这个标签时自动调用
23. System.out.println(“doEndTag”);
24. EmployeeDao employeeDao = new EmployeeDao();
25. ArrayList<Employee> employees = employeeDao.queryEmployeesByJobID(jobID);
26. //显示为表格
27. JspWriter out = pageContext.getOut();
28. try {
29. out.print(“<table>”);
30. out.print(“<tr>”);
31. out.print(“<td>ID</td>”);
32. out.print(“<td>Name</td>”);
33. out.print(“<td>Email</td>”);
34. out.print(“<td>Birthday</td>”);
35. out.print(“<td>JobID</td>”);
36. out.print(“</tr>”);
37. for(Employee employee:employees){
38. out.print(“<tr>”);
39. out.print(“<td>”+employee.getEmployeeId()+”</td>”);
40. out.print(“<td>”+employee.getFirstName()+” “+employee.getLastName()+”</td>”);
41. out.print(“<td>”+employee.getEmail()+”</td>”);
42. out.print(“<td>”+employee.getHireDate()+”</td>”);
43. out.print(“<td>”+employee.getJboId()+”</td>”);
44. out.print(“</tr>”);
45. }
46. out.print(“</table>”);
47. } catch (IOException e) {
48. e.printStackTrace();
49. }
50. return this.EVAL_PAGE; //让标签后面的JSP继续执行
51. }
52. public String getJobID() {
53. return jobID;
54. }
55. public void setJobID(String jobID) {
56. this.jobID = jobID;
57. }
58.}
package wang.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 wang.dao.EmployeeDao;
import wang.po.Employee;
//通过性别属性来显示
public class DisplayByJobIDTag extends TagSupport {
private String jobID;
public DisplayByJobIDTag() {
System.out.println(“DisplayAllTag构造函数”);
}
public int doStartTag() throws JspException {
// 系统开始运行这个标签时自动调用
System.out.println(“doStartTag”);
return this.SKIP_BODY; //空体标签,不要对体求值
}

public int doEndTag() throws JspException {
// 系统结束运行这个标签时自动调用
System.out.println(“doEndTag”);
EmployeeDao employeeDao = new EmployeeDao();
ArrayList<Employee> employees = employeeDao.queryEmployeesByJobID(jobID);
//显示为表格
JspWriter out = pageContext.getOut();
try {
out.print(“<table>”);
out.print(“<tr>”);
out.print(“<td>ID</td>”);
out.print(“<td>Name</td>”);
out.print(“<td>Email</td>”);
out.print(“<td>Birthday</td>”);
out.print(“<td>JobID</td>”);
out.print(“</tr>”);
for(Employee employee:employees){
out.print(“<tr>”);
out.print(“<td>”+employee.getEmployeeId()+”</td>”);
out.print(“<td>”+employee.getFirstName()+” “+employee.getLastName()+”</td>”);
out.print(“<td>”+employee.getEmail()+”</td>”);
out.print(“<td>”+employee.getHireDate()+”</td>”);
out.print(“<td>”+employee.getJboId()+”</td>”);
out.print(“</tr>”);
}
out.print(“</table>”);
} catch (IOException e) {
e.printStackTrace();
}
return this.EVAL_PAGE; //让标签后面的JSP继续执行
}
public String getJobID() {
return jobID;
}
public void setJobID(String jobID) {
this.jobID = jobID;
}
}
在EmployeeDao中添加按JobID查询的方法,代码如下

[java] view plaincopyprint?
01.public ArrayList<Employee> queryEmployeesByJobID(String jobID) {
02. ArrayList<Employee> employees = new ArrayList<Employee>();
03. String sql = “”;
04. if(jobID == null) {
05. sql = “select * from employees”;
06. }
07. else {
08. sql = “select * from employees where JOB_ID=’”+jobID+”‘”;
09. }
10. try {
11. this.initialConnection();
12. ResultSet rs = conn.createStatement().executeQuery(sql);
13. while(rs.next()) {
14. Employee employee = new Employee();
15. employee.setEmployeeId(rs.getString(“EMPLOYEE_ID”));
16. employee.setFirstName(rs.getString(“FIRST_NAME”));
17. employee.setLastName(rs.getString(“LAST_NAME”));
18. employee.setEmail(rs.getString(“EMAIL”));
19. employee.setHireDate(rs.getString(“HIRE_DATE”));
20. employee.setJboId(rs.getString(“JOB_ID”));
21. employees.add(employee);
22. }
23. } catch (SQLException e) {
24. e.printStackTrace();
25. } finally {
26. this.closeConnection();
27. }
28. return employees;
29.}
public ArrayList<Employee> queryEmployeesByJobID(String jobID) {
ArrayList<Employee> employees = new ArrayList<Employee>();
String sql = “”;
if(jobID == null) {
sql = “select * from employees”;
}
else {
sql = “select * from employees where JOB_ID=’”+jobID+”‘”;
}
try {
this.initialConnection();
ResultSet rs = conn.createStatement().executeQuery(sql);
while(rs.next()) {
Employee employee = new Employee();
employee.setEmployeeId(rs.getString(“EMPLOYEE_ID”));
employee.setFirstName(rs.getString(“FIRST_NAME”));
employee.setLastName(rs.getString(“LAST_NAME”));
employee.setEmail(rs.getString(“EMAIL”));
employee.setHireDate(rs.getString(“HIRE_DATE”));
employee.setJboId(rs.getString(“JOB_ID”));
employees.add(employee);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closeConnection();
}
return employees;
}
在emp.tld中新增标签项,代码如下

[xhtml] view plaincopyprint?
01.<tag>
02. <name>displayByJobID</name>
03. <tagclass>wang.tags.DisplayByJobIDTag</tagclass>
04. <attribute> <!– 注册属性 –>
05. <name>jobID</name>
06. <required>false</required> <!– 是否必需 –>
07. </attribute>
08.</tag>
<tag>
<name>displayByJobID</name>
<tagclass>wang.tags.DisplayByJobIDTag</tagclass>
<attribute> <!– 注册属性 –>
<name>jobID</name>
<required>false</required> <!– 是否必需 –>
</attribute>
</tag>
编写displayByJobID.jsp文件,代码如下

[xhtml] view plaincopyprint?
01.<%@ page language=”java” import=”java.util.*” pageEncoding=”ISO-8859-1″%>
02.<%@ taglib uri=”http://wang.mytag.emp” prefix=”emp”%>
03.<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
04.<html>
05. <head>
06. <title>My JSP ‘displayAll.jsp’ starting page</title>
07. </head>
08. <body>
09. <emp:displayByJobID jobID=”IT_PROG”></emp:displayByJobID>
10. </body>
11.</html>
<%@ page language=”java” import=”java.util.*” pageEncoding=”ISO-8859-1″%>
<%@ taglib uri=”http://wang.mytag.emp” prefix=”emp”%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>My JSP ‘displayAll.jsp’ starting page</title>
</head>
<body>
<emp:displayByJobID jobID=”IT_PROG”></emp:displayByJobID>
</body>
</html>
部署项目,启动服务器,运行页面,得到正确的结果。