Taglibrary descriptor.

Một phần của tài liệu luận văn ứng dụng sử dụng mô hình web là “kiến trúc mô hình một và hai” – “jsp model 1 and 2 architecture” (Trang 35 - 44)

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 tồ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 taglibdirective 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.*;

import javax.servlet.jsp.tagext.*; // tag extension

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

-

- TTaagghhaannddlleerr

Đố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 Tag là doStartTag và doEndTag. doStartTag được triệu gọi khi

JSP container gặp start tag, nĩ trả về SKIP_BODY vì thân tag

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; } (adsbygoogle = window.adsbygoogle || []).push({});

}

-

- TTLLDDeelleemmeenntt

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>

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

Svth: Đinh Lê Giang Trang 39

- - JJSSPPppaaggee 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. - - ĐĐịịnnhhnngghhĩĩaaccáácctthhuuộộccttíínnhhttrroonnggttaagghhaannddlleer.r.

Đố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 { (adsbygoogle = window.adsbygoogle || []).push({});

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

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; }

}

-

- TTLLDDeelleemmeenntt

Đố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>

<name>helloWorld</name>

<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> - - JJSSPPppaaggee 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"/>

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

Svth: Đinh Lê Giang Trang 41

</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. (adsbygoogle = window.adsbygoogle || []).push({});

-

- TTaagghhaannddlleerr

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.

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 và 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 tồ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();

bc.clearBody(); try {

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

throw new JspTagException("TransformTag: " + e.getMessage()); } return SKIP_BODY; } } - - TTLLDDeelleemmeenntt

TLD ở đây chỉ sữa đổi lại các ví dụ trên trong bodycontent tag

đặ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.

- - JJSSPPppaaggee 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

Svth: Đinh Lê Giang Trang 43

-

- TTaagghhaannddlleerr (adsbygoogle = window.adsbygoogle || []).push({});

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: P Phhạạmmvvii CCĩĩtthhểểttrruuyyccậậppttừừ TThhờờiiggiiaannssốốnngg 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

Ngồ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;

} (adsbygoogle = window.adsbygoogle || []).push({});

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()); } 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

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

Svth: Đinh Lê Giang Trang 45

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

} }

-

- TTLLDDeelleemmeenntt

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> ... - - JJSSPPppaaggee 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 ">

<% sv.begin() %>

Một phần của tài liệu luận văn ứng dụng sử dụng mô hình web là “kiến trúc mô hình một và hai” – “jsp model 1 and 2 architecture” (Trang 35 - 44)