LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 1
LUẬN VĂN TỐT NGHIỆP
KHOA
CƠNG NGHỆ THƠNG TIN
Đề tài
Xây dựng và ứng dụng JavaServer Pages (JSP) trong
phân tích thiết kế hệ thống cơ sở dữ liệu
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 2
Phần I
GIỚI THIỆU VỀ NGƠN NGỮ CÀI ĐẶT
Chương I
CĂN BẢN VỀ JSP
JavaServer Pages (JSP) là một kỹ thuật server-side do đó chúng ta khơng
thể thực hiện bất kỳ hành động nào ở client. JSP cho phép chúng ta tách thành
phần động của trang ra khỏi thành phần tĩnh HTML. Rất đơn giản, chúng ta
chỉ cần viết một tài liệu HTML bình thường rồi sau đó bao quanh mã của
thành phần động trong các tag đặc biệt, hầu hết các tag bắt đầu với <% và kết
thúc với %>. Ví dụ, đây là một phần của trang JSP, có kết quả trả về là
“Thanks for reading Van Dau book.” với URL là
http://localhost:8100/thanhk.jsp?title=Van+Dau
Thanks for reading <i><%=request.getParameter(“title”)%><i>book.
Kỹ thuật JSP là một thành phần trong đại gia đình Java; nó sử dùng ngơn
ngữ kịch bản dựa vào ngơn ngữ lập trình Java, và các trang JSP được biên dịch
thành servlets. Từ đó chúng ta cũng nhận biết được, JSP thì khơng phụ thuộc
bất kỳ nền (platform) nào. Nó đáp ứng được khuynh hướng của Sun
MicroSystem là “write one, run anywhere”.
Các trang JSP có thể gọi các thành phần JavaBeans, Enterprise
JavaBeans (EJB) hoặc custom tags để thực hiện các xử lý trên server. Và như
thế, kỹ thuật JSP là thành phần chủ chốt trong kiến trúc khả chuyển của Java
cho những ứng dụng dựa vào Web.
Như đã biết, JSPs sẽ biên dịch thành servlets nhưng JSP khơng thể thay
thế servlet vì các lý do sau:
Một số tác vụ được giải quyết rất tốt bằng servlet. Ví dụ, các ứng dụng
xuất ra dữ liệu nhị phân hoặc chỉ xác định nơi gởi trở lại cho người dùng
(bằng cách dùng response.sendRedirect) được dùng servlet thì tốt nhất.
Một số tác vụ khác lại được giải quyết rất tốt bằng JSP như các tình huống
mà cấu trúc nền tảng của trang HTML là cố định nhưng các giá trị trong nó
lại thay đổi.
Còn các tác vụ còn lại cần sự kết hợp cả servlet và JSP. Ví dụ, trong u
cầu gốc được trả lời bằng một servlet mà thực hiện mọi cơng việc, lưu trữ
các kết quả trong các Beans và điều phối u cầu này đến một trong những
trang JSP có thể hiển thị nó.
Cả ba định hướng này đều có chổ đứng của nó. Chẳng có định hướng
nào hổ trợ đầy đủ cho mọi ứng dụng .
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 3
Trước khi đi vào chi tiết cơng nghệ JSP, chúng tơi có một vài so sánh các
cơng nghệ được sử dụng trong ứng dụng với các cơng nghệ khác.
I. So sánh JSP với các cơng nghệ khác.
I.1. JSP với ASP
ASP là cơng nghệ tương đương từ Microsoft. JSP có ba lợi thế so với
ASP.
- Phần động được viết bằng Java, chứ khơng phải bằng các ngơn ngữ
script như VBScript, JavaScript. Vì thế nó mạnh mẽ hơn tốt hơn đối với các
ứng dụng phức tạp cần các thành phần sử dụng lại.
- JSP chạy được trên nhiều hệ điều hành và web servers khác nhau ngay
cả với IIS của Microsoft (cần có plugins từ Webphere, JRun, )
- Hỗ trợ sự mở rộng tag với custom tag.
I.2. JSP với PHP
Lợi điểm của JSP với PHP cũng như với ASP. JSP được viết bằng Java
mà chúng ta đã biết với các API mở rộng cho mạng, truy cập cơ sở dữ liệu,
các đối tượng phân tán, … trong khi với PHP đòi hỏi chúng ta phải học cả một
ngơn ngữ mới.
II. Các thành phần script của JSP.
Các thẻ bọc mã trong JSP cho phép chúng ta chèn mã vào servlet mã sẽ
được phát sinh từ trang JSP. Có ba dạng sau:
Biểu thức có dạng <%= expressions %>, được định giá trị và chèn vào
luồng xuất của servlet.
Scriptlet có dạng <% code %>, được chèn vào phương thức _jspService
của servlet (được gọi là service).
Khai báo có dạng <%! code %>, được chèn vào thân của lớp servlet, như
là các field của lớp thơng thường.
T
T
e
e
m
m
p
p
l
l
a
a
t
t
e
e
t
t
e
e
x
x
t
t
Trong nhiều trường hợp, phần lớn các trang JSP chỉ bao gồm HTML
tĩnh, được biết như là template text. Có hai ngoại lệ phụ cho quy tắc “template
text được chuyển thẳng sang HTML tĩnh”. Đầu tiên, nếu chúng ta muốn có
<% trong luồng xuất thì chúng ta cần phải đặt <\% trong template text. Thứ
hai, nếu chúng ta muốn có chú thích trong JSP mà khơng có trong tài liệu kết
quả, dùng:
<% JSP comments %>
Chú thích HTML có dạng:
<! HTML comments >
thì được chuyển qua tài liệu HTML thơng thường.
C
C
ú
ú
p
p
h
h
á
á
p
p
X
X
M
M
L
L
Trong JSP có rất nhiều element có cú pháp XML như jsp:useBean,
jsp:include, jsp:setProperty, Tuy nhiên scripting elements lại có hai dạng cú
pháp sau:
JSP Syntax XML Syntax
<% = Expressions %>
<jsp:expression>
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 4
Java code
</jsp:expression>
<% Scriptlets %> <jsp:scriptlet>
Java code
</jsp:scriptlet>
<%! Declarations %> <jsp:declaration>
Java code
</jsp:declaration>
II.1. Các biến được định nghĩa sẵn trong JSP
Để đơn giản hố mã trong các biểu thức hay scriptlets trong JSP, người
ta cung cấp cho chúng ta chín đối tượng đã được định nghĩa trước, có người
còn gọi là các đối tượng ngầm định. Do các khai báo trong JSP nằm ngồi
phương thức _jspService (được gọi bởi service) nên các đối tượng này khơng
cho phép các khai báo truy cập vào.
request
Biến này có kiểu là javax.servlet.http.HttpServletRequest, có phạm vi
trong một u cầu (request). Nó cho phép chúng ta truy cập vào các tham số
của request như loại request (GET, POST, …) và các incoming HTTP header
(cookies).
response
Có kiểu là javax.servlet.http.HttpServletResponse, có phạm vi tồn trang
(page). Chú ý rằng vì luồng xuất thì thường làm vật đệm cho nên việc gán mã
tình trạng của HTTP và response header thì hợp lý trong JSP, mặc dù điều này
thì khơng được phép trong servlet một khi đã có luồng xuất nào được gởi đến
client.
out
Có kiểu javax.servlet.jsp.JspWriter và phạm vi trong một trang (page).
Dùng để gởi các thơng xuất đến client. Đối tượng out được dùng thường
xun trong scriptlets, các biểu thức tự động được đưa vào luồng xuất nên
hiếm khi cần tham chiếu đến đối tượng này.
session
Có phạm vi trong một phiên truyền (session) và kiểu tương ứng là
javax.servlet.http.HttpSession. Gọi về các phiên truyền được tạo tự động vì thế
biến này vẫn còn kết nối ngay cả chẳng có một tham chiếu incoming session
nào. Một ngoại lệ là nếu chúng ta sử dụng thuộc tính session của page
directive để tắc các phiên truyền, mà lại cố tham chiếu đến biến session thì sẽ
gây ra các lỗi vào lúc trang JSP được dịch thành servlet.
application
Biến này có kiểu là javax.servlet.ServletContext, có phạm vi trong tồn
ứng dụng (application). ServletContext lấy từ một đối tượng cấu hình servlet là
getServletConfig().getContext(). Các trang JSP có thể lưu trữ dữ liệu persistent
trong đối tượng ServletContext tốt hơn là trong các biến thể hiện.
ServletContext có các phương thức setAttribute và setAttribute mà cho phép
chúng ta lưu trữ dữ liệu
config
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 5
Biến này có phạm vi trang (page) và có kiểu tương ứng là
javax.servlet.ServletConfig.
pageContext
Biến này có kiểu là javax.servlet.jsp.PageContext và có phạm vi là trang
(page). pageContext cho phép một điểm truy cập duy nhất tới nhiều thuộc tính
của trang và cung cấp một nơi thuận tiện để lưu trữ dữ liệu dùng chung. Biến
pageContext lưu trữ giá trị của javax.servlet.jsp.PageContext cùng với trang
hiện hành. Có thể xem chi tiết trong chương II về JavaBeans.
page
Biến này đồng nghĩa với this và điều này thì khơng hữu ích trong ngơn
ngữ lập trình Java, có kiểu là java.lang.Object và có phạm vi trang (page).
exception
Trong một trang lỗi, chúng ta có thể truy cập vào đối tượng exception.
Biến này có kiểu là java.lang.Throwable và phạm vị là trang (page).
II.2. Biểu thức trong JSP
Biểu thức trong JSP được dùng để chèn các giá trị trực tiếp vào luồng
xuất. Nó có dạng sau:
<%= Java expressions %>
Biểu thức này được định trị, được chuyển thành chuỗi, và được chèn
vào trong trang. Sự định trị diễn ra ở thời gian runtime (khi trang được u
cầu) và do đó có đầy đủ quyền truy cập các thơng tin của u cầu này. Ví dụ
sau đây mơ tả ngày/giờ mà trang được u cầu:
Current time: <%= new java.util.Date() %>
Trong Java mỗi câu lệnh đều có dấu ‘;’ kết thúc dòng. Tại sao biểu thức
trong JSP lại khơng có dấu ‘;’? Vì biểu thức này được đưa vào luồng xuất
chẳng hạn như PrintWriter. Với ví dụ trên có thể chuyển vào servlet như sau:
PrintWriter out = response.getWriter();
out.println(“Current time:” + new java.util.Date());
Biểu thức như là giá trị trong elements khác.
Biểu thức có thể được sử dụng trong các thuộc tính của các elements
khác. Giá trị từ các biểu thức này sẽ được tính vào thời gian u cầu (request
time). Các elements cho phép sử dụng biểu thức trong các thuộc tính của
chúng là:
Tên Element Tên thuộc tính
jsp:setProperty name và value
jsp:include Page
jsp:forward Page
jsp:param Value
II.3. JSP scriptlets
Scriptlets là những đoạn mã có chứa bất kỳ mã Java nào nằm giữa “<%”
và “%>”. Nếu chúng ta muốn thực hiện thứ gì đó phức tạp hơn là chỉ chèn vào
một biểu thức đơn giản thì JSP scriptlets cho phép chúng ta thêm bất kỳ đoạn
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 6
mã Java nào vào trang JSP. Các scriptlets này được đưa vào phương thức
_jspService (mà được gọi bởi service) của servlet. Có cú pháp:
<% Java Code %>
II.4. Khai báo trong JSP
Một khai báo trong JSP cho phép chúng ta định nghĩa các phương thức
hoặc các trường (biến) có phạm vi tồn trang. Khai báo sẽ được chèn vào
trong lớp của servlet (bên ngồi phương thức _jspService được gọi bởi service
để xử lý một u cầu). Một khai báo có dạng sau:
<%! Java Code %>
Các khai báo trong JSP thì khơng phát sinh ra bất kỳ thơng xuất nào,
chúng thường được dùng để liên kết với các biểu thức hoặc scriptlets. Chẳng
hạn, đây là một trang JSP mà in ra số lần truy cập vào trang.
III. Xử lý nhúng và chuyển hướng giữa các trang
Trong q trình xử lý và chuyển dữ liệu cho form chúng ta có thể nhúng
và triệu gọi những trang JSP khác với trang hiện hành.Ví dụ chúng ta có thể
đưa một trang HTML hoặc JSP vào trong trang JSP hiện tại để hổ trợ thêm thư
viện hay tính năng bổ sung nào đó. Hay khi nhận được dữ liệu submit từ trình
khách, trang JSP nhận được dữ liệu có thể chuyển hướng hoặc triệu gọi đến
trang JSP khác.
III.1. Nhúng file vào trang với chỉ thi include
Chỉ thị <%include %> thường dùng để dem một nội dung file .html hay
jsp bên ngồi vào trang hiện hành. Cú pháp sử dụng như sau:
<%@include file = “filename”%>
Ví dụ: Trong chương trình chúng ta có sử dụng các hàm thư viện chứa
trong file Common.jsp. Thư viện này được đưa vào trang JSP hiện hành như
sau:
<%@include file = “Common.jsp”%>
III.2. Sử dụng thẻ <jsp:include>
Chỉ thị %@include % chỉ dùng để nhúng các mã nguồn tĩnh. Nếu muốn
nhúng kết quả kết xuất từ các trang jsp, servlet hay .html khác vào trang hiện
hành chúng ta sử dụng thẻ <jsp:include> với cú pháp như sau:
<jsp:page include page = “filename” flush = “true”/>
Ví dụ: trong chương trình sử dụng thẻ <jsp:include> để nhúng kết quả
của trang Header.jsp, Footer.jsp vào các trang JSP như sau:
<jsp:include page = “Header.jsp” flush = “true”/>
…
<jsp:include page = “Footer.jsp” flush = “true”/>
III.3. Chuyển tham số bằng thẻ <jsp:param>
Khi nhúng trang bằng thẻ <jsp:include> bạn có thể chuyển tham số cho
trang được nhúng để nhận được kết xuất linh động hơn bằng cách sử dụng thẻ
con <jsp:param>.
Ví dụ
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 7
testParam.jsp
<jsp: include page = “testParam2.jsp” flush = “true”>
<jsp:param name = “greeting” value = “Welcome”/>
<jsp:include>
<%
out.println (“Goi tham so từ test1.jsp”);
%>
testParam2.jsp
<%
String param = request.getParameter (“greeting”);
out.println (“Goi tham so tu test2.jsp”);
out.println (“param: “ + param);
%>
III.4. Chuyển tiếp đến trang khác với thẻ <jsp:include>
Chúng ta sử dụng thẻ <jsp:forward> để triệu gọi và chuyển dữ liệu cho
trang jsp khác xử lý. Trong ví dụ sau chúng ta có 3 trang JSP. Trang thứ nhất
hiển thị form đăng nhập u cầu nhập vào tên username và password. Trang
thứ hai kiểm tra: nếu username, password trùng với username, password cho
trước thì thơng báo đăng nhập thành cơng, còn nếu khơng đúng hoặc rỗng sẽ
chuyển đến trang thứ 3 thơng báo u cầu đăng nhập những trường còn thiếu.
Ví dụ:
Login.jsp
<html>
<%
String param = request.getParameter (“sError”);
if (param.length() !=0)
{
out.println (“<b>”+ param + “</b>”);
}
%>
<form method = post action = “security.jsp”>
Username: <input type = text name = “username”>
Password: <input type = password name = “password”>
<input type = submit value = Login>
</form>
</html>
security.jsp
<html>
<%
String user = (String) request.getParametrer(“username”);
if (user.equals (“admin”))
{
%>
<jsp:forward page = “thongbao.jsp”/>
<%
} else {
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 8
%>
<jsp:include page = “login.jsp” flush = “true”>
<jsp:param name = “sError” value = “Ban nhap lai username &
password”/>
<jsp:include>
<%}%>
</html>
thongbao.jsp
<html>
Ban dang nhap voi usernam: <%=request.getParameter
(“username”)%>
Password: <%=request.getParameter (“password”)%>
</html>
III.5. Thẻ jsp:plugin
Phương cách đơn giản nhất để sử dụng jsp:plugin là cung cấp cho nó bốn
thuộc tính: type, code, width, height. Chúng ta định giá trị “applet” cho thuộc
tính type và ba thuộc tính còn lại sử dụng giống như APPLET tag bình
thường. Với ngoại lệ là các action thì có cú pháp XML nên các thuộc tính
trong nó cũng phải theo qui ước XML. Ví dụ với APPLET tag trong HTML
<APPLET CODE=“MyApplet.class”
WIDTH=457 HEIGHT=350>
</APPLET>
sử dụng jsp:plugin action như sau:
<jsp:plugin type=“applet”
code=“MyApplet.class”
width=“457” height=“350” />
Ngồi bốn thuộc tính này jsp:plugin còn có các thuộc tính sau và hầu hết
giống (nhưng khơng phải là tất cả) như các thuộc tính của APPLET tag.
codebase, align, archive, hspace, name, vspace, title
Giống như APPLET tag.
jreversion
Xác định số phiên bản của Java Runtime Environment, các giá trị có thể
nhận là “1.1”, “1.2”.
nspluginurl
URL cho Netscape mà có thể download Plug-In. Giá trị mật định sẽ
hướng người dùng đến web site của Sun, nhưng với intranet chúng ta có thể
muốn chỉ dẫn người dùng đến một bản sao cục bộ.
iepluginurl
URL cho Internet Explorer mà có thể download Plug-In.
I
I
I
I
I
I
.
.
6
6
.
.
T
T
h
h
ẻ
ẻ
j
j
s
s
p
p
:
:
f
f
a
a
l
l
l
l
b
b
a
a
c
c
k
k
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 9
jsp:fallback cung cấp văn bản thay thế đối với các trình duyệt khơng hổ trợ
OBJECT hay EMDEB. Chúng ta sử dụng action này giống như là dùng văn bản thay
thế được đặt trong APPLET tag
<APPLET CODE=“MyApplet.class”
WIDTH=457 HEIGHT=350>
<B> Error: this example requires Java. </B>
</APPLET>
với
<jsp:plugin type=“applet”
code=“MyApplet.class”
width=“457” height=“350” >
<jsp:fallback>
<b> Error: this example requires Java. </b>
</jsp:fallback>
</jsp:plugin>
I
I
I
I
I
I
.
.
7
7
.
.
C
C
h
h
u
u
y
y
ể
ể
n
n
t
t
r
r
a
a
n
n
g
g
page directive cho phép chúng ta điều khiển cấu trúc của servlet bằng
cách đưa vào các lớp, đặt MIME type, …. Một page directive có thể được đặt
bất cứ nơi nào trong trang JSP.
<%@ page import=“java.util.*, com.vandau.*” %>
page directive định nghĩa một số thuộc tính phụ thuộc vào trang và giao tiếp
giữa các thuộc tính này với JSP container.
language
Định nghĩa ngơn ngữ kịch bản được sử dụng trong scriptlets, biểu thức
và khai báo. Trong JSP 1.2 là phiên bản mới nhất chỉ có hổ trợ “java” cho
thuộc tính này do đó “java” này cũng là giá trị mật định.
<%@ page language=“java” %>
extends
Thuộc tính này chỉ định lớp cha (superclass) của servlet sẽ được phát
sinh cho trang JSP, có dạng sau:
<%@ page extends=“package.class” %>
Chú ý rằng khi sử dụng thuộc tính này phải hết sức cẩn thận vì tại server
có thể đã dùng lớp cha mật định.
import
Thuộc tính này mơ tả các kiểu sẵn dùng trong mơi trường kịch bản (theo
java). Chúng ta có thể import vào từng lớp hoặc cả một gói (package).
<%@ page import=“package.class | package.*” %>
Nếu import vào nhiều lớp hay packages thì cách nhau dấu “,”.
session
Thuộc tính session kiểm sốt liệu có hay khơng một trang tham gia vào
HTTP session. Có hai giá trị “true” và “false”. Mật định là “true”, chỉ ra rằng
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 10
biến ngầm định session nên được nối kết với session hiện hành. Giá trị “false”
có nghĩa rằng chẳng có session nào được sử dụng tự động và nếu cố truy cập
vào biến session sẽ trả lỗi vào lúc trang được dịch thành servlet.
buffer
Thuộc tính này xác định kích thước của vùng đệm được sử dụng bởi biến
out. Có dạng sau:
<%@ page buffer=“none | sizekb” %>
Thuộc tính này có giá trị mật định là “8kb”, giá trị “none” chẳng có vùng
đệm nào được cấp và tất cả dữ liệu xuất sẽ được ghi trực tiếp qua
ServletResponse, PrintWriter.
autoFlush
Xác định liệu luồng xuất có vùng đệm được tự động flush (giá trị “true”
mật định) khi vùng đệm đầy hay sẽ tung ra một ngoại lệ khi vùng đệm tràn
(“false”).
Chú ý rằng sẽ khơng hợp lý nếu đặt autoFlush=“false” khi
buffer=“none”.
isThreadSafe
Xác định mức độ an tồn của tiểu trình (thread) được cài đặt trong trang
(với giao tiếp SingleThreadModel), “true” là giá trị mật định.
info
Định nghĩa một chuỗi có thể truy xuất từ servlet bằng phương thức
getServletInfo().
<%@ page info=“Some Message” %>
errorPage
Thuộc tính này xác định một trang JSP nên bất kỳ các ngoại lệ nào được
tung ra nhưng khơng bắt ngoại lệ này trong trang hiện hành.
<%@ page errorPage=“Ralative URL” %>
Ngoại lệ tung ra sẽ có sẵn trong biến ngầm định exception.
isErrorPage
Xác định trang JSP hiện thời có thể hoạt động như một trang lỗi cho một
trang JSP khác. Giá trị “false” là mật định cho thuộc tính này.
contentType
Thuộc tính này gán Content-Type cho response header, mơ tả kiểu
MIME của tài liệu được gởi đến client. Thuộc tính contentType có một trong
hai dạng sau:
<%@ page contentType=“MIME-Type” %>
<%@ page contentType=“MIME-Type; charset=Character-Set” %>
Một số kiểu MIME-Type thường dùng: “text/html”, “text/xml”,
“text/plain”, “image/gif”, “image/jpeg”.
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 11
pageEncoding
Định nghĩa bộ mã hóa ký tự cho trang JSP (character encoding), thuộc
tính này hổ trợ cho bộ mã Unicode và Latin-1, có giá trị mật định là “ISO-
8859-1”
III.8. Chuyển hướng sang trang mới với sendRedirect()
Ngồi việc chuyển tiếp chúng ta có thể sử dụng phương thức
sendRedirect() để chuyển hướng và triệu gọi trang JSP khác xử lý. Sự khác
nhau giữa chuyển tiếp (forward) và chuyển hướng (redirect) đó là lệnh
sendRedirect () chỉ thực hiện triệu gọi trang mà khơng chuyển tham số của
trang hiện hành cho trang chuyển hướng.
Ví dụ: từ trang security.jsp ta có thể chuyển hướng đến trang
thongbao.jsp bằng lệnh như sau:
<%
…
response.sendRedirect (“thongbao.jsp”);
%>
IV. SERVLET
IV.1. Khái niệm
Servlet là các thành phần đối tượng nhúng trên trình chủ Web server thực
hiện xử lý u cầu và sinh ra các trang Web động trả về máy khách. Để sử
dụng được Servlet chúng ta cần có các trình chủ hiểu Java và hỗ trở triệu gọi
Servlet như Apache, Jrun, Web Logic ….
Ví dụ sau là một Servlet cơ bản
import javax.servlet.*;
import java.io.*;
public class helloWorldServlet extends GnericServlet
{
public void service (ServletRequest request, ServletResponse response)
throws IOException
{
response.setContextType (“text/html”);
PrintWriter out = response.getWriter ();
out.println (“<html>”);
out.println (“<body>”);
out.println (“<h1> Hello World Servlet! </h1>”);
out.println (“</body>”);
out.println (“</html>”);
}
}
IV.2. Các phương thức xử lý cơ bản của Servlet
Lớp GenericServlet là phần cài đặt tổng qt cho đặc tả giao tiếp
(interface) mang tên Servlet. Theo đặc tả của giao tiếp Servlet do Sun đưa
ra một servlet cơ bản cần có những phương thức phục vụ cho các nhu cầu
khởi tạo (init), hoạt động và phục vụ (service), hủy (destroy), trả về thơng
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 12
tin cấu hình (getServletConfig), trả về thơng tin tư thân của servlet
(getServletInfo). Cụ thể lớp giao tiếp Servlet được mơ tả như sau:
interface Servlet
{
void destroy ()
ServletConfig getServletConfig ();
String getServletInfo ();
void init (ServletConfig config);
void service (ServletRequest req, ServletResponse res);
}
IV.2.1. Phương thức khởi tạo init ()
public void init ()
Phương thức khởi tạo này được gọi khi lần đầu tiên trình chủ Web server
nạp mã thực thi của servlet từ tập tin .class vào bộ nhớ và bắt đầu cho phép
servlet hoạt động. Chúng ta có thể dựa vào phương thức này để khởi tạo các
biến mơi trường và giá trị ban đầu cần thiết cho q trình thực thi servlet sẽ
diễn ra tiếp theo. Thường trong phương thức init () ta khởi tạo giá trị mảng,
tạo sẵn kết nối với cơ sở dữ liệu, nạp các lớp thư viện cần thiết…. Ví dụ chúng
ta có thể nạp trình điều khiển JDBC truy xuất cơ sở dữ liệu, tạo sẵn kết nối đến
nguồn dữ liệu cho servlet trong phương thức init () như sau:
public class staffView extends GenericServlet
{
String DBDriver = “sun.jdbc.odbc.JdbcOdbcDriver”;
String strConn = “jdbc:odbc:quanliNV”;
Connection con;
public init ()
{
Class.forName (DBDriver). newInstance ();
Conn = DriverManager.getConnection (strConn);
}
}
IV.2.2. Phương thức phục vụ service ()
public void service (ServletRequest req, ServletResponse res) throws
IOException
Sau khi phương thức init () đã hồn tất, trình chủ Web server sẽ triệu gọi
đến phương thức phục vụ service (). Phương thức này được xem là trung tâm
xử lý của servlet mà chúng ta cần phải cài đặt. Khi trình chủ nạp servlet vào
bộ nhớ, phương thức init () chỉ được gọi duy nhất một lần trong phương thức
service () có thể được triệu gọi nhiều lần ứng với mỗi u cầu servlet phát sinh
từ trình duyệt phía máy khách. Bên trong phương thức service () chúng ta có
thể sử dụng đối tượng tham số ServletRequest và ServletResponse để tiếp
nhận dữ liệu từ trình khách chuyển lên và kết xuất kết quả phản hồi trở lại
trình khách.
Ví dụ:
public void service (ServletRequest request, ServletResponse response)
throws IOException
{
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 13
response.setContextType (“text/html”);
PrintWriter out = response.getWriter ();
out.println (“<html>”);
out.println (“<body>”);
…
}
IV.2.3. Phương thức hủy destroy ()
Khi servlet khơng còn dùng nữa hoặc hết thời gian qui định lưu giữ trong
bơ nhớ của trình chủ Web server, nó sẽ bị trình chủ giải phóng. Trước khi
servlet bị hủy phươg thức destroy () sẽ được gọi. Nếu như chúng ta dùng
phương thức init () để thực hiện khởi tạo biến cho servlet thì phương thức
destroy () ngược lại có thể dùng để dọn dẹp tài ngun mà các biến chiếm giữ,
đóng các kết nối mà phương thức init () đã mở…
Ví dụ: public destroy ()
{
conn.close ();
}
IV.2.4. Phương thức getServletConfig () và getServletInfo ()
Hai phương thức này nhằm mục đích cung cấp thơng tin. Phương thức
getServletConfig () giúp người sử dụng servlet có được đối tượng
ServletConfig chưa các thơng tin khởi tạo từ mơi trường ngồi đưa vào servlet,
getServletInfo () trả về một chuỗi thơng tin mơ tả ý nghĩa và mục đích của
servlet.
public String getServletInfo ();
public ServletConfig getServletConfig ();
IV.3. Chu trình sống của Servlet và JSP
Chu trình sống của servlet
Chu trình sống tính từ khi servlet bắt đầu được hệ thống gọi nạp vào bộ
nhớ cho đến khi nó bị loại khỏi trình chủ Web server vì khơng còn cần đến
nữa. Q trình sống của servlet trải qua các giai đoạn sau:
Nạp servlet
Khởi tạo servlet
Thực thi servlet
Dọn dẹp servlet
Nạp servlet
Tùy theo điều kiện, một servlet có thể nạp vào bộ nhớ ở 3 thời điểm khác
nhau: khi server khởi động, khi ngừoi quả trị u cầu hoặc khi trình duyệt triệu
gọi servlet từ máy khách. Hầu hết các Web server điều cho phép bạn chọn
danh sách servlet sẽ được ưu tiên nạp lúc Web server khởi động. Tuy tốn ít
thời gian hơn nhưng sau đó servlet đã trong trạng thái sẵn sàng có thể phục vụ
trình khách bất kỳ lúc nào.
Khởi tạo servlet
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 14
Trình chủ Web server khởi tạo servlet bằng cách gọi đến phương thức
init () mà servlet cài đặt. Phương thức này chỉ gọi một lần duy nhất. Chúng ta
có thể lợi dụng cơ hội này để khởi tạo các biến tồn cục mà servlet sẽ sử dụng
sau này.
Thực thi servlet
Khi trình duyệt hoặc các trang JSP triệu gọi servlet thơng qua địa chỉ
URL, trình chủ Web server sẽ chính thức gọi servlet thực thi thơng qua các
phương thức như doGet (), doPost () hoặc service (). Ví dụ khi chúng ta gọi
trực tiếp servlet từ địa chỉ URL, phương thức doGet () của servlet sẽ được gọi.
Nếu chúng ta gọi servlet thơng qua thao tác post cua thẻ <form> thì phương
thức doPost () sẽ được gọi. Sau khi các phương thức này được gọi thực thi
xong, servlet vẫn giữ lại trong bộ nhớ để phục vụ cho các lần triệu gọi tiếp
theo. Đây cũng chính là ưu điểm làm cho servlet thực thi nhanh các ứng dụng
CGI.
Dọn dẹp servlet
Servlet khơng giữ lại trong bộ nhớ vĩnh viễn, sẽ đến lúc cần loại servlet
khỏi bộ nhớ. Ví dụ như khi nhà quản trị muốn dừng hệ thống, muốn
Webserver khởi động lại để giải phóng rác trong bộ nhớ tăng hiệu suất thực
hiện…. Trước khi chấm dứt, Web server sẽ gọi đến phương thức hủy destroy
() của servlet. Đây là cơ hội để servlet thực hiện một số thao tác dọn dẹp cần
thiết như lưu dữ liệu xuống đĩa, ghi nhớ trạng thái của servlet để phục vụ cho
lần khởi động sau, đóng kết nối với cơ sở dữ liệu…. Và mặc dù Java có thể tự
động thu gom rác trong bộ nhớ nhưng nếu chúng ta đã cấp phát một khối
lượng bộ nhớ lớn cho servlet trong q trình làm việc, chúng ta nên thực hiện
giải phóng chúng trong phương thức destroy ().
Chu trình sống của JSP
Tương tự như chu trình sống của servlet, trang JSP cũng có cbhu trình
sống xác định tính từ khi hệ thống đọc biên dịch trang JSP, gọi thực thi và loại
trang khỏi bộ nhớ. Chu trình sống của JSP trải qua các giai đoạn sau:
Biên dịch trang JSP
Nạp trang
Khởi tạo
Thực thi
Dọn dẹp
Biên dịch trang JSP
Khi trình duyệt u cầu trang JSP, ví dụ triệu gọi trang JSP bằng URL
http://localhost:8100/Default.jsp. Web server sẽ kiểm tra trang JSP đã được
biên dịch hay chưa. Nếu chưa biên dịch hoặc đã biên dịch nhưng trang JSP
mới vừa thay đổi trong mã nguồn thì Web server sẽ thực hiện biên dịch trang
JSP. Q trình biên dịch JSP thực tế là chuyển trang JSP thành servlet. File
biên dịch . class của trang sẽ được đặt trong thư mục đệm. Như chúng ta thấy,
q trình biên dịch trang chỉ diễn ra một lần. Nếu trang đã biên dịch và sau đó
chúng ta khơng có thay đổi gì trong trang nguồn thì q trình biên dịch sẽ
khơng xảy ra, do đó tốc độ thực thi trang sẽ nhanh hơn. Sau khi trang đã được
biên dịch, mã trang sẽ được nạp vào bộ nhớ để thực thi.
Nạp trang
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 15
Kể từ giai đoạn này, q trình nạp trang tương tư như servlet. Chỉ có một
khác biệt đó là servlet chỉ được nạp một lần trong khi mã trang JSP mặc dù đã
biên dịch nhưng phải nạp lại nhiều lần mỗi khi Web server nhận được u cầu
trang từ trình duyệt.
Khởi tạo
Khi nạp mã trang thành cơng, Web server sẽ gọi đến phương thức khởi
tạo trang. Và mặc dù, JSP được biên dịch ra servlet như phương thức khởi tạo
cho trang JSP lại mang tên jspInit () chứ khơng phải là init () như servlet.
Thực thi
Sau q trình khởi tạo, Web server sẽ gọi đến phương thức _jspService
(). Phương thức _jspService sẽ chuyển cho chúng ta hai lớp đối tượng
HttpServletRequest và HttpServletResponse để đọc và ghi kết xuất trả về trình
khách.
Dọn dẹp
Khi trang JSP đã thực thi xong, trình chủ Web server sẽ gọi phương thức
jspDestroy () để giải phóng mã trang khỏi bộ nhớ. Tương tự như trong servlet,
chúng ta có thể cài đặt phương thức jspDestroy () thực hiện chức năng giảp
phóng vùng nhớ hoặc đóng kết nối trả tài ngun về cho hệ thống.
IV.4. Ưu và khuyết điểm của Servlet so với JSP
Do mã trang JSP khi thực thi đều được biên dịch ra servlet cho nên tất cả
những gì servlet làm được cũng đồng nghĩa với trang JSP làm được. Viết trang
JSP đơi lúc đơn giản hơn viết servlet vì khơng cần phải qua bước đăng ký và
biên dịch thủ cơng. Tuy nhiên chúng ta cũng nên biết một số trường hợp phân
biệt giữa JSP và servlet và cách sử dụng chúng.
JSP có thể trộn lẫn mã Java với các thẻ HTML cho nên thiết kế trang JSP
thường đơn giản và dễ bổ sung hơn so với servlet. Tuy nhiên đây cũng là yếu
tố khơng nên lạm dụng đối với JSP. Nếu chúng ta tập trung tất cả mã Java vào
cũng với mã HTML, một khi dự án mỡ rộng và trở nên phức tạp, việc bảo trì
và nâng cấp ứng dụng Web với hàng trăm trang JSP sẽ rất khó khăn. Trong
q trình phát triển ứng dụng Web theo nhóm, việc trộn lẫn mã JSp sẽ rất khó
khăn. Trong qua trình phát triển ứng dụng Web theo nhóm, việc trộn lẫn mã
Java và HTML trong trang JSP cho thấy khơng hiệu quả. Khó có thể tách rời
giữa cơng việc viết mã cho ứng dụng và nhóm xây dựng giao diện. Mã trang
JSP ở dạng thuần văn bản nên thường khơng che được mã nguồn của logic
chương trình.
Với servlet, tuy phải biên dịch và đăng ký thủ cơng với trình chủ nhưng
bù lại tính bảo mật cao hơn. Chúng ta chủ cần cung cấp cho trình chủ Web
server bản servlet nhị phân (file .class) đã qua bước biên dịch mã khơng cần
đến mã nguồn của servlet ban đầu. Mặc khác, các servlet có thể tương tác liên
hồn, với nhau để tạo nên những kết xuất tùy biến và đa dạng trước khi trả kết
quả về cho trình khách. Servlet có thể phân rã các đơn thể của dự án và phát
triển độc lập nhau như các thành phần riêng biệt để ráp lại trong một tổng thể
chung. Tuy nhiên, việc kết xuất trong servlet thường dựa vào phương thức
print () hoặc println (). Cơng việc quyết định giao diện cho kết xuất hồn tồn
phụ thuộc vào lập trình viên với hàng loạt các lệnh print () hay println () rất
khó quản lý.
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 16
Quyết định sử dụng JSP, Servlet hay kết hợp cả hai là tuỳ vào từng dự án
và mục đích của chương trình mà chúng ta muốn phát triển. Thơng thường đối
với những dự án nhỏ, u cầu thời gian nhanh, JSP là lưa chọn thích hợp nhất.
Trường hợp với dự án cần sự độc lập và chỉ thiên về xử lý ta nên sử dụng
servlet. Trường hợp với dự án lớn chúng ta nên kết hợp cả servlet và JSP. Mơ
hình kết hợp tốt nhất giữa servlet và JSP thường được gọi là MCV (Model –
View – Controler) trong đó servlet đóng vai trò trung tâm điều khiển
(controler) đưa ra các quyết định xử lý. JSP đóng vai trò thể hiện giao diện hay
hiển thị dữ liệu đã xử lý. Quy trình tính tốn logic của ứng dụng được giao lại
cho các thành phần JavaBean hay EJB.
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 17
Chương II
T
T
a
a
g
g
L
L
i
i
b
b
r
r
a
a
r
r
i
i
e
e
s
s
I
I
.
.
T
T
a
a
g
g
l
l
i
i
b
b
r
r
a
a
r
r
y
y
l
l
à
à
g
g
ì
ì
?
?
Trong kỹ thuật JavaServer Pages, các action là các element có thể tạo ra
và truy cập vào các đối tượng của ngơn ngữ lập trình và xuất vào những luồng
xuất chuẩn như màn hình, máy in,… JSP định nghĩa ra chín action chuẩn mà
phải được cung cấp bởi bất kỳ engine nào.
Ngồi các action chuẩn này, từ JSP v1.1 trở lên cho phép xây dựng và
phát triển các module có thể dùng lại được gọi là custom action. Trong trang
JSP, một custom action được triệu gọi bằng cách dùng custom tag. Một tag
library là một tập các custom tag.
Các ứng dụng có thể được thực hiện bằng custom action bao gồm xử lý
form, truy cập cơ sở dữ liệu và các dịch vụ ở mức xí nghiệp khác như email,
quản lý thư mục và điều khiển luồng. Trước khi custom action xuất hiện thì
JSP có một cơ chế dùng lại mã là các thành phần JavaBean kết hợp với
scriplet. Tuy nhiên với JavaBean có một bất lợi là xây dựng phức tạp và khó
quản lý.
Các custom action làm dịu được vấn đề này bằng cách mang lại các lợi
ích dưới góc độ khác của việc module hố tính sử dụng lại cho các trang JSP.
Các custom action gói gọn lại các tác vụ để chúng có thể được dùng lại trong
hơn một ứng dụng và tăng hiệu xuất bằng cách khuyến khích phân chia cơng
việc giữa các nhà phát triển thư viện và người sử dụng thư viện. Các tag
library của JSP được tạo bởi các nhà phát triển, là người thành thạo ngơn ngữ
lập trình Java và là chun gia trong giao tiếp với cơ sở dữ liệu và các dịch vụ
khác. Các tag library được dùng bởi các nhà thiết kế ứng dụng web, là người
có thể chỉ tập trung vào cách thức hiển thị hơn là quan tâm đến cách truy cập
cơ sở dữ liệu và các dịch vụ khác.
Một số đặt tính của các custom tag là:
- Chúng có thể được tuỳ biến thơng qua các thuộc tính từ một trang
đang gọi.
- Chúng được phép truy cập vào tất cả đối tượng có sẵn trong trang JSP.
- Chúng có thể thay đổi lời đáp mà được phát sinh bởi một trang đang
gọi.
- Chúng có thể được lồng với nhau và cho phép các tương tác phức tạp
trong một trang.
- Chúng có thể truyền thơng với nhau. Chúng ta có thể tạo và khởi tạo
một thành phần JavaBean, tạo một biến tham chiếu đến Bean đó trong một tag
và sau đó sử dụng Bean này trong tag khác.
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 18
I
I
I
I
.
.
C
C
á
á
c
c
h
h
d
d
ù
ù
n
n
g
g
c
c
á
á
c
c
t
t
a
a
g
g
s
s
t
t
r
r
o
o
n
n
g
g
J
J
S
S
P
P
Phần này trình bày cách thức mà tác giả của trang web sử dụng tag
library trong JSP và giới thiệu các loại tag khác nhau. Các ví dụ trong phần
này sẽ được định nghĩa trong phần III.
I
I
I
I
.
.
1
1
.
.
K
K
h
h
a
a
i
i
b
b
á
á
o
o
c
c
á
á
c
c
t
t
a
a
g
g
l
l
i
i
b
b
r
r
a
a
r
r
y
y
Trang JSP sẽ sử dụng các tag được định nghĩa trong một tag library bằng
cách đưa vào taglib directive trong trang trước bất kỳ custom tag được sử
dụng:
<%@ taglib uri = ‘/tlt’ prefix = ‘tlt’ %>
Thuộc tính uri tham chiếu tới URI đó là định danh duy nhất cho tag
library. URI có thể là URI tương đối hay tuyệt đối. Nếu URI tương đối thì nó
phải được ánh xạ đến một URI tuyệt đối trong taglib element của bộ mơ tả
triển khai ứng dụng Web, tập tin cấu hình này cùng với ứng dụng Web được
phát triển theo bản đặt tả Java Servlet và JavaServer Pages.
Thuộc tính prefix định nghĩa một tiếp đầu ngữ để phân biệt với các tag
library khác, do đó thuộc tính này giải quyết được vấn đề xung đột về các tên
tag.
I
I
I
I
.
.
2
2
.
.
C
C
á
á
c
c
l
l
o
o
ạ
ạ
i
i
t
t
a
a
g
g
Những custom action được diễn đạt bằng cú pháp XML. Chúng có start
tag, nội dung và end tag:
<tlt:tag>
body
</tlt:tag>
Một tag mà khơng có nội dung được biểu diễn như sau:
<tlt:tag />
I
I
I
I
.
.
2
2
.
.
1
1
.
.
C
C
á
á
c
c
t
t
a
a
g
g
đ
đ
ơ
ơ
n
n
g
g
i
i
ả
ả
n
n
Một tag đơn giản sau triệu gọi một action và xuất ra lời chào “Hello
World.”.
<tlt:helloWorld />
I
I
I
I
.
.
2
2
.
.
2
2
.
.
C
C
á
á
c
c
t
t
a
a
g
g
c
c
ó
ó
t
t
h
h
u
u
ộ
ộ
c
c
t
t
í
í
n
n
h
h
Một start tag của custom action có thể chứa các thuộc tính dưới dạng attr
= ‘value’. Các thuộc tính này tuỳ biến các tham số dùng trong các phương
thức của một lớp java.
Các thuộc tính có thể được gán một hay nhiều tham số trong một đối
tượng request hoặc từ một hằng chuổi. Chỉ có các kiểu thuộc tính trong bảng
sau mới có thể được gán từ các giá trị tham số của request và của các hằng
chuổi
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 19
K
K
i
i
ể
ể
u
u
t
t
h
h
u
u
ộ
ộ
c
c
t
t
í
í
n
n
h
h
P
P
h
h
ư
ư
ơ
ơ
n
n
g
g
t
t
h
h
ứ
ứ
c
c
v
v
a
a
l
l
u
u
e
e
O
O
f
f
c
c
h
h
u
u
y
y
ể
ể
n
n
c
c
h
h
u
u
ổ
ổ
i
i
boolean or Boolean
java.lang.Boolean.valueOf(String)
byte or Byte
java.lang.Byte.valueOf(String)
char or Character
java.lang.Character.valueOf(String)
double or Double
java.lang.Double.valueOf(String)
int or Integer
java.lang.I
nteger.valueOf(String)
float or Float
java.lang.Float.valueOf(String)
long or Long
java.lang.Long.valueOf(String)
Giá trị thuộc tính có dạng <%= expression %> được tính vào thời gian
u cầu. Giá trị của biểu thức tuỳ thuộc vào kiểu thuộc tính được xác định
trong đối tượng cài đặt tag còn gọi là tag handler (tag handler trong phần định
nghĩa các tag).
<tlt:helloWorld name=’Phan Van Dau’/>
I
I
I
I
.
.
2
2
.
.
3
3
.
.
C
C
á
á
c
c
t
t
a
a
g
g
c
c
ó
ó
n
n
ộ
ộ
i
i
d
d
u
u
n
n
g
g
Tag có thể bao hàm các custom tag, scripting element, HTML, và nội
dung nằm giữa start tag và end tag. Trong ví dụ sau sẽ đưa ra thơng tin “lời
chào” được cung cấp trong thân tag thay vì trong thuộc tính của nó.
<tlt:helloWorld>
Phan Van Dau
</tlt:helloWorld>
i
i
.
.
C
C
á
á
c
c
t
t
a
a
g
g
đ
đ
ị
ị
n
n
h
h
n
n
g
g
h
h
ĩ
ĩ
a
a
c
c
á
á
c
c
b
b
i
i
ế
ế
n
n
k
k
ị
ị
c
c
h
h
b
b
ả
ả
n
n
Một tag có thể định nghĩa ra một biến mà biến này được dùng trong cùng
một trang. Ví dụ sau đây minh hoạ cách thức định nghĩa và sử dụng một biến
chứa một đối tượng được trả về.
i
i
i
i
.
.
K
K
ế
ế
t
t
h
h
ợ
ợ
p
p
c
c
á
á
c
c
t
t
a
a
g
g
Các tag kết hợp với nhau bằng các phương pháp của các đối tượng dùng
chung. Trong ví dụ sau, tag1 tạo một đối tượng có tên là obj1, sau đó được sử
dụng lại bởi tag2. Qui tắc này được khuyến khích bởi bảng đặt tả JSP, một tag
tạo ra một tên với thuộc tính id và tag thứ hai có thuộc tính name để dùng lại
tên này.
<tlt:tag1 id=’obj1’ attr2=’value’/>
<tlt:tag2 name=’obj1’/>
Trong ví dụ kết tiếp, dùng các tag lồng nhau tương tự như trong XML và
HTML.
<tlt:outerTag>
<tlt:innerTag />
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 20
<tlt:outerTag>
i
i
i
i
i
i
.
.
Đ
Đ
ị
ị
n
n
h
h
n
n
g
g
h
h
ĩ
ĩ
a
a
c
c
á
á
c
c
t
t
a
a
g
g
Để sử dụng các custom tag trong trang JSP, chúng ta cần phải định nghĩa
ba thành phần riêng biệt:
Phát triển tag handler và các lớp trợ giúp cho tag.
Khai báo tag trong bộ mơ tả thư viện tag (tag library descriptor) dưới
dạng tập tin XML.
Tạo tập tin JSP có sử dụng custom tag.
Phần này mơ tả các thuộc tính của tag handler và các bộ mơ tả thư viện
tag, cũng trình bày cách phát triển tag handler và các element của bộ mơ tả
thư viện đối với mỗi loại tag được giới thiệu trong phần trước.
I
I
I
I
.
.
3
3
.
.
T
T
a
a
g
g
h
h
a
a
n
n
d
d
l
l
e
e
r
r
Tag handler là một đối tượng được gọi lên bởi JSP container để định trị
cho custom tag trong xuốt q trình thực thi của trang JSP có tham chiếu tới
một tag nào đó. Các phương thức của tag handler được gọi bởi lớp cài đặt
trang JSP vào các thời điểm khác nhau trong xuốt q trình định trị cho tag.
Khi gặp start tag của custom tag thì lớp cài đặt trang JSP gọi các phương
thức để khởi tạo các giá trị thích hợp và sau đó triệu gọi phương thức
doStartTag. Khi gặp end tag của custom tag thì phương thức doEndtag được
gọi.
Tuỳ theo mục đích của từng custom tag mà chúng ta xử lý các phương
thức thích hợp trong từng giao tiếp cài đặt. Bảng sau mơ tả các loại tag có các
phương thức tương ứng để xử lý.
L
L
o
o
ạ
ạ
i
i
t
t
a
a
g
g
h
h
a
a
n
n
d
d
l
l
e
e
r
r
C
C
á
á
c
c
p
p
h
h
ư
ư
ơ
ơ
n
n
g
g
t
t
h
h
ứ
ứ
c
c
c
c
ầ
ầ
n
n
x
x
ử
ử
l
l
ý
ý
Simple
doStartTag, doEndTag, release
Attributes
doStartTag, doEndTag, set/getAttribute1 N
Body, No Interaction
doStartTag, doEndTag, release
Body, Interaction
doStartTag, doEndTag, release, doInitBody, doAfterBody
Tag handler có sự truy cập vào API mà cho phép nó truyền thơng với
trang JSP. Con đường vào API này là đối tượng pageContext, qua đó tag
handler có thể truy cập vào mọi đối tượng ngầm định khác như request,
session, application từ trang JSP. Các đối tượng ngầm định có thể có các
thuộc tính kết hợp với chúng. Các thuộc tính như thế được truy cập qua các
phương thức [get/set]Attribute thích hợp.
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 21
Nếu tag được lồng nhau thì tag handler cũng có thể truy cập handler
này (được gọi là parent) cùng với tồn bộ tag.
Các tag handler phải được cài đặt hai giao tiếp hoặc Tag hoặc BodyTag.
Các giao tiếp có thể được dùng để lấy đối tượng Java đã tồn tại và tạo ra một
tag handler. Để định nghĩa các tag handler mới chúng ta có thể dùng các lớp
TagSupport và BodyTagSupport như là các lớp cơ sở (xem 4. Tag handler
được triệu gọi như thế nào?).
I
I
I
I
.
.
4
4
.
.
T
T
a
a
g
g
l
l
i
i
b
b
r
r
a
a
r
r
y
y
d
d
e
e
s
s
c
c
r
r
i
i
p
p
t
t
o
o
r
r
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:
HelloWorldTag.java
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library1.1//EN"
"
<! 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 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>
I
I
I
I
.
.
5
5
.
.
C
C
á
á
c
c
v
v
í
í
d
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
1. Các tag đơn giản.
-
-
T
T
a
a
g
g
h
h
a
a
n
n
d
d
l
l
e
e
r
r
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 22
Đố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 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:
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;
}
}
-
-
T
T
L
L
D
D
e
e
l
l
e
e
m
m
e
e
n
n
t
t
Các tag mà khơng có thân phải khai báo nội dung của thân là rỗng.
helloworld.tld
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"
<! Nếu có JSP v1.2 thì đổi lại
" >
<! a tag library descriptor >
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>vandau</shortname>
<uri></uri>
<info>
A tag library from authors at http://localhost:8100/
</info>
<tag>
<name>helloWorld</name>
<tagclass>HelloWorldTag</tagclass>
<info>Ví dụ với tag đơn giản nhất</info>
<! ‘EMPTY’ is insensitive case >
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 23
<bodycontent>EMPTY</bodycontent>
</tag>
<! Other tags defined later >
</taglib>
-
-
J
J
S
S
P
P
p
p
a
a
g
g
e
e
hello.jsp
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html>
<head>
hello.jsp (tiếp theo)
<%@ taglib uri = "helloworld.tld" prefix = "vandau" %>
<title>
<vandau:helloWorld />
</title>
<! stylesheet để hiển thị các tag như h1, … >
<link rel = "stylesheet" href ="JSP-Styles.css" type =
"text/css"/>
</head>
<body>
<h1><vandau:helloWorld /></h1>
<vandau:helloWorld />
</body>
</html>
I
I
I
I
.
.
5
5
.
.
1
1
.
.
C
C
á
á
c
c
t
t
a
a
g
g
c
c
ó
ó
t
t
h
h
u
u
ộ
ộ
c
c
t
t
í
í
n
n
h
h
-
-
Đ
Đ
ị
ị
n
n
h
h
n
n
g
g
h
h
ĩ
ĩ
a
a
c
c
á
á
c
c
t
t
h
h
u
u
ộ
ộ
c
c
t
t
í
í
n
n
h
h
t
t
r
r
o
o
n
n
g
g
t
t
a
a
g
g
h
h
a
a
n
n
d
d
l
l
e
e
r
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:
HelloWorldTag.java
public HelloWorldTag extends TagSupport {
private String name = “World.”;
public void setName(String name) {
this.name = name;
}
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 24
public int doStartTag() throws JspException {
try {
pageContext.getOut().print("Hello " + name);
} catch (Exception ex) {
throw new JspTagException("HelloWorldTag: " +
e.getMessage());
HelloWorldTag.java
}
return SKIP_BODY;
}
public int doEndTag() {
return EVAL_PAGE;
}
}
-
-
T
T
L
L
D
D
e
e
l
l
e
e
m
m
e
e
n
n
t
t
Đối với mỗi thuộc tính chúng ta phải xác định thuộc tính nào được 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:
TLD file (overwrite helloworld.tld)
<! đoạn này tương tự như mục 1) >
<tag>
<name>helloWorld</name>
<tagclass>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>
-
-
J
J
S
S
P
P
p
p
a
a
g
g
e
e
paramtag.jsp
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html>
<head>
<%@ taglib uri = "helloworld.tld" prefix = "vandau" %>
LUẬN VĂN TỐT NGHIỆP Khóa 1998-2003
SVTH: Phan Văn Đấu GVHD: Nguyễn Hồng Quang Trang 25
<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><vandau:helloWorld name = "TH 40" /></h1>
<vandau:helloWorld name = "TH40" />
</body>
</html>
I
I
I
I
.
.
5
5
.
.
2
2
.
.
C
C
á
á
c
c
t
t
a
a
g
g
c
c
ó
ó
n
n
ộ
ộ
i
i
d
d
u
u
n
n
g
g
-
-
T
T
a
a
g
g
h
h
a
a
n
n
d
d
l
l
e
e
r
r
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 ngun 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.