Taglibrary descriptor.

Một phần của tài liệu đồ án tốt nghiệp đề tài quản lý công việc trên web (Trang 40)

III. Định nghĩa các tag.

2.Taglibrary descriptor.

Tag library descriptor (TLD) là một tài liệu XML dùng để mô tả thư viện tag. Một TLD chứa toàn bộ thông tin về thư viện và mỗi tag chứa trong thư viện. JSP container và các công cụ phát triển JSP sử dụng TLD để xác định các tag.

Các element của TLD sau dùng để định nghĩa thư viện tag:

Code 21: HelloWorldTag.java

<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib

PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library1.1//EN"

"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <!-- a tag library descriptor -->

<taglib>

<tlibversion> <!-- Phiên bản của thư viện tag -->

<!-- Phiên bản của JSP mà tag handler phụ thuộc --> <jspversion>

<!--Tên mặt định đơn giản có thể dùng bởi công cụ tạo trang JSP để tạo tên với giá trị gợi nhớ; chẳng hạn shortname có thể được dùng như giá trị tiếp đầu ngữ thích hợp trong taglib directive

và/hoặc tạo ra các tiếp đầu ngữ cho các id --> <shortname>

<uri> <!-- URI duy nhất xác định tag library --> <info> <!-- Thông tin mô tả về tag library --> <tag> ... </tag> ... </taglib>

Tag element yêu cầu đối với mọi tag để xác định một lớp có trong thư

viện tag. <tag> <tagclass>classname</tagclass> ... </tag> 3. Các ví dụ.

Để tạo các custom tag chúng ta cần hai import gói cơ bản: import javax.servlet.jsp.*;

Đồ án tốt nghiệp Gvhd: Ts. Nguyễn Thúc Hải

a) Các tag đơn giản.

-

- Tag handlerTag handler

Đối với các tag đơn giản chỉ cần cài đặt hai phương thức của giao tiếp TagdoStartTagdoEndTag. doStartTag được triệu gọi khi JSP container gặp start tag, nó trả về SKIP_BODY vì thân

tag chẳng có nội dung nào cả. Ngược lại khi gặp end tag thì JSP container gọi doEndTag, trả về EVAL_PAGE nếu phần còn lại của trang cần phải định trị, nếu không trả về SKIP_PAGE.

Lớp tag handler sẽ được cài đặt như sau:

Code 22: HelloWorldTag.java

public HelloWorldTag extends TagSupport { public int doStartTag() throws JspException {

try { pageContext.getOut().print("Hello World."); } catch (Exception ex) {

throw new JspTagException("HelloWorldTag: " + e.getMessage());

}

return SKIP_BODY; }

public int doEndTag() { return EVAL_PAGE; }

}

-

- TLD elementTLD element

Các tag mà không có thân phải khai báo nội dung của thân là rỗng.

Code 23: helloworld.tld

<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib

PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <!--Nếu có JSP v1.2 thì đổi lại

"http://java.sun.com/j2ee/dtds/jsptaglibrary_1_2.dtd"--> <!-- a tag library descriptor -->

<taglib>

<tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion>

<shortname>legiang</shortname> <uri></uri>

<info>

A tag library from authors at http://www.legiang.com/. </info>

<tag>

<name>helloWorld</name>

<tagclass>com.legiang.HelloWorldTag</tagclass> <info>Ví dụ với tag đơn giản nhất</info>

<!-- ‘EMPTY’ is insensitive case --> <bodycontent>EMPTY</bodycontent> </tag>

<!-- Other tags defined later... --> </taglib> - - JSP pageJSP page Code 24: hello.jsp <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html> <head>

Code 24: hello.jsp (tiếp theo)

<%@ taglib uri = "helloworld.tld" prefix = "legiang" %> <title>

<legiang:helloWorld /> </title>

<!-- stylesheet để hiển thị các tag như h1, …-->

<link rel = "stylesheet" href ="JSP-Styles.css" type = "text/css"/> </head> <body> <h1><legiang:helloWorld /></h1> <legiang:helloWorld /> </body> </html> b) Các tag có thuộc tính. -

Đồ án tốt nghiệp Gvhd: Ts. Nguyễn Thúc Hải

Đối với mỗi thuộc tínch của tag, chúng ta phải định nghĩa theo phong cách của JavaBean, tức là phải có phương thức get/set[Attribute] trong

tag handler.

Hãy nhớ rằng, nếu thuộc tính được đặt tên là id và tag handler kết thừa từ lớp TagSupport thì chúng ta không cần định nghĩa các phương thức get/set[Attribute] bởi vì những thứ này đã được TagSupport làm sẵn.

Lớp tag handler sẽ được cài đặt như sau:

Code 25: HelloWorldTag.java (sữa lại trong Code 22 )

public HelloWorldTag extends TagSupport { private String name = “World.”;

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

}

public int doStartTag() throws JspException { try {

pageContext.getOut().print("Hello " + name); } catch (Exception ex) {

throw new JspTagException("HelloWorldTag: " + e.getMessage());

Code 25: HelloWorldTag.java (sữa lại trong Code 22) (tiếp theo)

}

return SKIP_BODY; }

public int doEndTag() { return EVAL_PAGE; }

}

-

- TLD elementTLD element

Đối với mỗi thuộc tính chúng ta phải xác định thuộc tính nào được yêu cầu (bắt buộc) và giá trị nào có thể được xác định bởi biểu thức. Nếu thuộc tính của tag không bắt buộc thì tag handler nên cung ấp giá trị mật định.

TLD cho tag handler ở trên như sau:

Code 26: TLD file (overwrite helloworld.tld)

... <!-- đoạn này tương tự như mục 1) --> <tag>

<tagclass>com.legiang.HelloWorldTag</tagclass> <info>Ví dụ với tag đơn giản nhất</info>

<attribute>

<name>name</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute>

<!-- ‘EMPTY’ is insensitive case --> <bodycontent>EMPTY</bodycontent> </tag> - - JSP pageJSP page Code 27: paramtag.jsp <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html>

Code 27: paramtag.jsp (tiếp theo)

<head>

<%@ taglib uri = "helloworld.tld" prefix = "legiang" %> <title> Tag With Attributes </title>

<!-- stylesheet để hiển thị các tag như h1, …-->

<link rel = "stylesheet" href ="JSP-Styles.css" type = "text/css"/>

</head> <body>

<h1><legiang:helloWorld name = "BKHN University" /></h1>

<legiang:helloWorld name = "DHBK Ha Noi" /> </body>

</html>

c) Các tag có nội dung.

-

- Tag handlerTag handler

Tag handler cho loại này được cài đặt khác nhau phụ thuộc vào tag handler có tương tác với thân hay không. Tương tác có nghĩa là tag handler đọc hoặc sữa đổi nội dung của thân hoặc tạo ra giá trị lặp lại cho thân tag.

Đồ án tốt nghiệp Gvhd: Ts. Nguyễn Thúc Hải

Các tag có tương tác với phần thân: nếu tag handler không cần tương tác với phần thần thì tag handler này nên cài đặt giao tiếp Tag hoặc dẫn xuất từ lớp TagSupport. Nếu thân của tag cần định trị thì doStartTag cần phải trả về EVAL_BODY_INCLUDE, ngược lại trả về SKIP_BODY.

Các tag có tương tác với phần thân: tag handler phải cài đặt giao tiếp BodyTag hoặc BodyTagSupport, thường cài đặt phương thức doInitBody

doAfterBody. Hai phương thức này tương tác với nội dung của thân được chuyển vào tag handler bởi lớp cài đặt trang JSP. Đối tượng BodyContent cung cấp vài phương thức để đọc và ghi nội dung của nó. Tag handler sử dụng các phương thức getString, getReader của BodyContent để trích thông tin từ phần thân và phương thức writeOut(out) để ghi các nội dung của thân vào luồng xuất. Phương thức getPreviousOut thường được sử dụng để bảo đảm rằng kết quả trả về của tag handler thì có sẳn đối với toàn bộ tag handler. Các phương thức chính được dùng trong loại tag này:

doInitBody: được gọi sau khi nội dung của thân được gán nhưng trước khi được định giá trị, thường được dùng để thực hiện khởi tạo giá trị mà tuỳ thuộc vào nội dung của thân.

doAfterBody: được gọi sau khi nội dung của thân được định trị. Nếu thân được trị nhiều lần lặp đi lặp lại nên trả về EVAL_BODY_TAG, ngược lại trả về SKIP_BODY.

release: tag handler nên xác lập lại trạng thái của nó và giải

phóng các tài nguyên dành riêng bằng phương thức release. Ví dụ sau đọc nội dung của thân, chuyển nội dung đó, và sau đó ghi lại những thay đổi vào luồng xuất.

Code 28: TransformTag.java

public class TransformTag extends BodyTagSupport { public int doAfterBody() throws JspTagException { BodyContent bc = getBodyContent();

String body = bc.getString(); bc.clearBody();

try {

getPreviousOut().print(body.transform()); } catch (IOException e) {

throw new JspTagException("TransformTag: " + e.getMessage());

return SKIP_BODY; }

}

-

- TLD elementTLD element

TLD ở đây chỉ sữa đổi lại các ví dụ trên trong bodycontent tag và đặt tên file là transform.tld

<tag> ...

<bodycontent>JSP<bodycontent> <tag>

Với các tag có phần thân thì bodycontent tag có hai giá trị. Một là JSP, phần thân bao gồm custom tag, scripting element và văn bản HTML. Tất cả các thứ còn lại có giá trị là tagdependent. Chú ý rằng giá trị của element này không ảnh hưởng tới tiến trình thông dịch của thân.

- - JSP pageJSP page Code 29: transformtag.jsp <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html> <head>

<%@ taglib uri = "transform.tld" prefix = "legiang" %> <title> Tag With Body </title>

<!-- stylesheet để hiển thị các tag như h1, …-->

<link rel = "stylesheet" href ="JSP-Styles.css" type = "text/css"/>

</head> <body>

<h1> Tag With Body </h1> <legiang:transform>

Hi! BKHN University </legiang:transform> </body>

</html>

d) Các tag định nghĩa các biến kịch bản.

-

Đồ án tốt nghiệp Gvhd: Ts. Nguyễn Thúc Hải

Tag handler đảm nhận việc tạo và gán đối tượng được tham

chiếu bởi biến kịch bản vào ngữ cảnh có thể truy cập từ một trang. Để Làm được điều này bằng cách dùng hoặc phương thức

pageContext.setAttribute(name, value, scope) hoặc

pageContext.setAttribute(name, value). Thông thường một thuộc tính chuyển vào custom tag phải xác định “tên” của biến đối tượng; Tên này có thể truy xuất bằng cách gọi phương thức get[Attribute] của thuộc tính (xem 2) Các tag có thuộc tính).

Nếu giá trị của biến kịch bản phụ thuộc vào đối tượng hiện tại trong tag handler thì nó có thể truy xuất đối tượng này bằng cách dùng

pageContext.setAttribute(name, scope). Các giá trị của tham số scope được tóm tắc trong bảng sau:

Phạm vi

Phạm vi Có thể truy cập từCó thể truy cập từ Thời gian sống Thời gian sống

page Trang hiện hành

Cho tới khi lời đáp gởi trở lại user hoặc yêu cầu được chuyển tới trang mới

request Trang hiện hành và bất kỳ trang được include hay forward nào

Cho tới khi lời đáp gởi trở lại user

session

Yêu cầu hiện hành và bất kỳ yêu cầu tiếp theo trong cùng browser

Đời sống của một phiên làm việc (session)

application

Bất kỳ yêu cầu hiện tại và tương lai nào từ cùng một ứng dụng

Đời sống của một ứng dụng

Ngoài việc cài đặt giá trị của biến trong tag handler, chúng ta còn phải định nghĩa một lớp dẫn xuất từ lớp TagExtrInfo. Lớp này cung cấp thông tin cho JSP container về đặt tính của của biến kịch bản, phải cài đặt phương thức getVariableInfo để trả về một mảng các đối tượng VariableInfo chứa các thông tin sau: tên biến, lớp của biến, liệu biến này có tham khảo tới một giá trị đối tượng mới hay đã có, tính sẳn dùng của biến này.

Bảng sau mô tả tính sẳn dùng của biến kịch bản và các phương thức để xác lập và xác lập lại giá trị của biến.

Value Availability Methods

NESTED Giữa start tag và end tag.

Trong doInitBody và doAfterBody đối với tag

handler cài đặt BodyTag;

ngược lại trong doStartTag.

AT_BEGIN Từ start tag cho đến cuối trang.

Trong doInitBody,

doAfterBody, và doEndTag đối với tag handler cài đặt

BodyTag; ngược lại trong doStartTag và doEndTag. AT_END Sau end tag cho tới cuối trang. Trong doEndTag.

Lớp tag handler sau lấy dữ liệu từ JNDI lookup được lưu trữ như là thuộc tính của đối tượng pageContext cùng với tên của biến kịch bản.

Code 30: LookupTag.java

public LookupTag extends TagSupport { private String type;

private String name;

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

}

public void setType(String type) { this. type = type;

}

public int doStartTag() { return SKIP_BODY; }

public int doEndTag() throws JspException { try {

InitialContext context = new InitialContext(); Object obj = (Object)context.lookup(name); pageContext.setAttribute(getId(), obj);

Code 30: LookupTag.java (tiếp theo)

} catch(javax.naming.NamingException e) {

throw new JspException("Unable to look up " + name + " due to " + e.getMessage());

Đồ án tốt nghiệp Gvhd: Ts. Nguyễn Thúc Hải

return EVAL_PAGE; }

}

Biến kịch bản sẽ được định nghĩa trong lớp dẫn xuất từ lớp

TagExtraInfo. Do biến được truyền vào như các thuộc tính của tag nên sẽ được truy xuất bởi phương thức getAttributeString của lớp TagData và dùng để lấp đầy hàm tạo của VariableInfo. Để cho phép biến kịch bản được dùng trong phần còn lại của trang thì phạm vi của biến nên gán bằng AT_END.

Code 31: LookupTagTei.java

public class LookupTagTEI extends TagExtraInfo { public VariableInfo[] getVariableInfo(TagData data) { VariableInfo info1 = new VariableInfo( data.getAttributeString("id"), data.getAttributeString("type"), true, VariableInfo.AT_END); VariableInfo[] info = { info1 } ; return info;

} }

-

- TLD elementTLD element

Chúng ta cần phải báo cho JSP container biết nó nên dùng lớp

TagExtraInfo để tạo ra biến kịch bản với phạm vi thích hợp. Đoạn TLD có tên lookup.tld như sau:

Code 32: TLD file ... <tag> <tagclass>com.legiang.LookupTag </tagclass> <teiclass>com.legiang.LookupTagTEI</teiclass> <attribute> <name>name</name> <required>true<required>

<rtexprvalue>false</rtexprvalue> </attribute> <attribute> <name>type</name> <required>true<required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> ... - - JSP pageJSP page Code 33: JSP file ...

<%@ taglib uri = "lookup.tld" prefix = "legiang" %> <!-- dùng trong body của JSP -->

<legiang:lookup id = "sv" type = "UserTransaction" name = "java:comp/ UserTransaction ">

<!-- Giả sử trong lớp UserTransaction có phương thức begin --> <% sv.begin() %>

Một phần của tài liệu đồ án tốt nghiệp đề tài quản lý công việc trên web (Trang 40)