Center
of Excellence
Bài
1
Tính
lương trước thuế
Đây
là bài đầu tiên trong loạt bài phát triển các ứng dụng
web (web applications) dùng công nghệ JavaServer Faces (JSF).
Để dễ dàng tiếp thu, bạn cần có kiến thức về lập
trình hướng đối tượng bằng Java. Có thể tham khảo
loạt bài lập trình hướng đối tượng bằng Java tại đây. Vạn sự khởi đầu nan. Bạn nên đọc và thực
hành nhiều lần cho đến khi tự mình phát triển được
giải pháp mà không cần nhìn vào bài.
I.
Bài toán
Hãy
phát triển một web application để tính lương chính thức
(gross pay), hay còn được gọi là lương chưa trừ thuế,
của một nhân viên biết rằng thông tin để tính lương
bao gồm số giờ làm việc (number of hours worked, được
qui tròn về một số nguyên không âm) và lương một giờ
(hourly pay rate, là một số thực dương từ 6.00 trở lên,
đơn vị là USD, đô-la Mỹ). Sau đây là công thức tính
gross pay:
gross-pay
= number-of-hours-worked
x
hourly-pay-rate
Dưới
đây là màn hình giao diện (UI screen) mẫu.
Hình
1
II.
Giải pháp
Đầu
tiên ta thiết kế một user interface screen (UI screen) tĩnh
dùng ngôn ngữ thuần XHTML, sau đó dùng JSF để bổ sung
phần động, tức phần tương tác với người dùng
(user), rồi phát triển mã (code) tính toán. Tuy nhiên, trước
tiên ta cần tạo dự án (project) bằng việc dùng môi
trường phát triển tích hợp (Integrated Development
Environment – IDE) Netbeans. Phần phụ lục sẽ hướng dẫn
việc tải (download) và cài đặt (install) IDE này.
1.
Tạo JSF project
Kích
(click) vào File
menu, rồi chọn New
Project...
để
chuyển sang cửa sổ
New
Project.
Hình
2
Chọn
dự án (Choose
Project) bằng cách
chọn Java Web
trong mục Categories,
chọn tiếp Web
Application trong mục
Projects,
rồi click Next
để chuyển sang bước đặt
tên và xác định vị trí lưu trữ (Name
and Location).
Hình
3
Nhập
tên dự án vào ô Project
Name, ở đây ta đặt
là PaymentJSF.
(Có thể thay đổi vị trí lưu trữ của project bằng cách
click vào nút Browse.)
Click Next
để chuyển sang bước chọn
server (Server and
Settings).
Hình
4
Chọn
GlassFish Server 3.1
cho mục Server,
chọn Java EE 6 Web
cho mục Java EE
Version, rồi nhớ
chọn Enable Contexts
and Dependency Injection.
Sau đó click Next
để chuyển sang bước chọn Frameworks.
Hình
5
Chọn
JavaServer Faces
rồi click Finish.
Hình
6
2.
Thiết kế UI screen
Sau
khi tạo xong project, NetBeans chủ động tạo sẵn trang
(page) index.xhtml.
Hình
7
Nhận
xét rằng NetBeans đã sử dụng các thẻ (tag) JSF cho phần
đầu (head) và phần thân (body) của index.xhtml
page. Ta có thể quay về sử dụng những thẻ thuần XHTML
như sau
Hình
8
Kế đến, ta đặt
lại tiêu đề cho page.
Hình
9
Để
xem nhanh biểu diễn của page trong trình duyệt web (web
browser), ta kích phải (right-click) vào bên trong page, rồi
chọn View.
Hình
10
Đến
đây ta tổ chức các ô nhập và ô xuất bên trong.
Ta áp dụng <h:outputText> cho ô xuất Gross
pay nhằm ngăn không
cho user thay đổi nội dung ô này.
Hình
11a
Thêm vào đó là những hoa thị đỏ để nhắc nhở user, những giá trị phải nhập
Bên dưới <fieldset> block, ta nhóm hai nút lệnh (buttons) bên trong <div> block: Compute Gross Pay để user có thể yêu cầu application thực hiện việc tính toán, và Clear để xóa nội dung bên trong các ô nhập lẫn ô xuất.
Hình
11b
Bên dưới <fieldset> block, ta nhóm hai nút lệnh (buttons) bên trong <div> block: Compute Gross Pay để user có thể yêu cầu application thực hiện việc tính toán, và Clear để xóa nội dung bên trong các ô nhập lẫn ô xuất.
Hình
12
Để
tăng tính thẩm mỹ cho page, ta yêu cầu browser khi trình
bày phần body, phải chừa trống lề (margin) trái lẫn lề
phải một khoảng bằng 20% chiều ngang của browser (Hai giá
trị 0 có nghĩa là ta không thay đổi phần trên cũng như
phần dưới của page).
Hình
13
Kế
đến, ta sắp cho ngay ngắn các nhãn (label) bên trong
<fieldset>
block bằng cách qui định chiều rộng (width) của label là
170 pixels (điểm ảnh), không cho các thành phần khác lấn
vào chiều rộng qui định này (thông qua thuộc tính
float),
và canh lề phải (right) cho label (thông qua thuộc tính
text-align).
Hình
14
Sau đó ta canh lề
trái cho hai buttons để chúng thẳng hàng với các ô nhập
xuất ở trên.
Hình
15
3.
Dùng JSF để bổ sung phần động
Sau
khi kết thúc phần thiết kế UI screen tĩnh, ta tiến hành
bổ sung phần động bằng JSF để thực hiện phần tương
tác với user. Phần động bao gồm việc tạo managed bean
(hay còn gọi là backing bean, tức đối tượng làm nhiệm
vụ hỗ trợ), sau đó ràng buộc (bind) web page với managed
bean.
3.1.
Tạo managed bean
Managed
bean là một Java class chuyên biệt, đóng vai trò là cầu
nối giữa phần giao tiếp với user (UI) và phần tính toán
(model) bên trong application.
Ta
tạo managed bean tên là Index để hỗ trợ cho
index.xhtml bằng cách right-click vào Source Packages,
chọn New, rồi chọn Other... để chuyển sang
New File window.
Hình
17
Chọn
JavaServer Faces ở bảng Categories: bên trái, sau
đó chọn JSF Managed Bean ở bảng File Types: bên
phải, rồi click Next để chuyển sang bước đặt
tên và xác định vị trí lưu trữ (Name and Location).
Hình
18
Nhập
Index
vào ô Class
Name:,
nhập controller
vào ô Package:,
và chọn request
trong ô Scope:,
rồi click Finish.
(Trong
một số trường hợp,
request
được
thay bằng một chọn lựa khác. Với application
này, request
là
chọn lựa thích hợp.)
Hình
19
Hình
20
Quan
sát Index managed bean, ta thấy đây là một Java class
với hai phụ chú (annotation) là @Named và
@RequestScoped (do ta đã chọn request trong ô
Scope:), đồng thời managed bean còn có một phương
thức tạo đối tượng phi tham biến (no-arg constructor).
Đến
đây ta tiến hành xem xét các thành phần tương tác với
người dùng (UI components) bên trong index.xhtml để
quyết định xem managed
bean cần có những trường (field) nào. Ở đây index.xhtml
có ba loại UI components: input, output, và nút lệnh (button).
3.1.1.
Tạo fields cho input components
Application
của ta cần hai giá trị nhập từ user, đó là number of
hours worked và hourly pay rate, vì vậy ta cần có
hai fields kèm theo getter/setter tương ứng bên trong managed
bean.
Hình
21
Lưu
ý là đối với các fields trong managed bean, ta không dùng
kiểu dữ liệu nguyên thủy (primitive data type) mà dùng
kiểu đối tượng (object type). Chẳng hạn ở đây, thay
vì dùng int, ta đã dùng Integer cho hoursWorked.
Cũng vậy, ta đã dùng Double cho hourlyPayRate,
thay vì dùng double. Ngoài ra, ta không tạo thêm bất kỳ
constructor nào khác.
Khi
yêu cầu NetBeans phát sinh getter và setter cho fields,
right-click bên trong class, chọn Insert Code...
Hình
22
Chọn
Getter and Setter...
Hình
23
Đánh
dấu fields, rồi click Generate.
Hình
24
Hình
25
3.1.2.
Tạo field cho output component
Application
của ta chỉ có một output component đó là gross pay.
Đối với output component, ta chỉ cần getter (không cần
setter) bên trong managed
bean.
Hình
26
3.1.3.
Tạo phương thức (methods) cho buttons
Đối
với mỗi button, ta tạo một method trong managed
bean.
Chú
ý rằng kiểu kết quả trả về (return data type) của
computeGrossPay() bên trong Index managed bean là
void (thay vì double), bởi vì với cách phát
triển managed bean như trên, kết quả tính toán sẽ được
lưu vào grossPay field, và index.xhtml sẽ truy
xuất đến field này thông qua getter của nó.
3.2.
Ràng buộc web page với managed
bean
Trước
tiên ta cần áp dụng <h:form>block
cho bộ phận nào của index.xhtml
page có chứa những thành phần tương tác với user.
Hình
28
3.2.1.
Ràng buộc input components với managed
bean
Đối
với input components, ta thay <input> tag bằng JSF
tag tương ứng là <h:inputText> kèm theo thuộc
tính (attribute) value.
Hình
29
3.2.2.
Ràng buộc output component với managed
bean
Đối
với output component, ta không cần dùng JSF tag mà chỉ cần
bổ sung value attribute vào <input> tag.
Hình
30
3.2.3.
Ràng buộc buttons với managed
bean
Ta
thay <input> tag bằng JSF tag tương ứng là
<h:commandButton> kèm theo thuộc tính (attribute)
action với lệnh gọi computeGrossPay() và clear()
bên trong managed bean.
Hình
31
3.2.4.
Phát triển clear()
Phương
thức clear() liên quan đến việc xóa
nội dung bên trong các ô nhập và xuất, tức liên quan đến
các UI components, nên ta phát triển code ngay bên trong
managed bean.
Hình
32
4.
Phát triển code tính toán
Đây là phần
tính toán độc lập với tầng giao diện với người dùng
(presentation tier hay view). Ta gọi tầng này là business logic
hay model tier. Sự độc lập này sẽ
giúp ta dễ dàng tái dụng (reuse) business logic cho những
applications khác. Chẳng hạn, nếu yêu cầu của bài toán
bây giờ không phải là giao diện web, mà phải là giao
diện trên một máy tính đơn (desktop computer) hay trên một
thiết bị di động, ta chỉ cần tạo lại UI screen, còn
business logic thì vẫn giữ nguyên.
Code
của Payment class cùng với class kiểm thử (unit test)
tương ứng sẽ như sau
5.
Kết nối managed
bean với model
Sau
khi đã phát triển và kiểm thử thành công phần tính
toán, ta trở về managed
bean để triệu gọi lệnh tính toán và lưu kết quả vào
grossPay field.
Hình
36
Đến
đây, ta có thể thi hành application
bằng cách triển khai (deploy) project lên máy chủ web (web
server). Trong Projects
window, right-click vào tên project rồi chọn Run.
Hình
37
Ta nhập dữ liệu
cho Number of hours worked và
Hourly pay rate rồi
nhấn phím Enter
hoặc click Compute Gross Pay
button để xem kết quả tính toán.
Hình
38
Để xóa số liệu
trên form, ta click Clear
button.
6.
Kiểm tra tính hợp lệ của dữ liệu nhập
6.1.
Xử lý trường hợp để trống ô nhập
Khi thi hành
application, nếu user để trống ô Number of hours worked
hoặc Hourly pay rate,
application sẽ tung ngoại lệ NullPointerException.
Để buộc user phải nhập dữ liệu (data), ta bổ sung
required="true"
attribute vào <h:inputText>
tag.
Hình
39
Ngoài
ra, ta muốn thông báo lỗi phải nằm cạnh vị trí xảy
ra lỗi để giúp user dễ dàng sửa sai. Ta đặt cạnh mỗi
<h:inputText>
một <h:message>
tag. Nhờ id
attribute của <h:inputText>
và for
attribute của <h:message>
mà JSF biết được thông báo nào dành cho (for) thành phần
nào (id).
Hình
40
Ta
có thể thay đổi nội dung của thông báo lỗi bằng cách
thêm requiredMessage attribute
vào <h:inputText>.
Hình
41
6.2.
Xử lý trường hợp nhập data không đúng yêu cầu
Đến đây,
application vẫn chưa có khả năng bắt lỗi nếu user nhập
vào một giá trị âm cho Number of hours worked.
Ta phải lồng <f:validateLongRange>
vào trong <h:inputText>,
đồng thời bổ sung validatorMessage
attribute. Ở đây ta qui định rằng số giờ làm việc tối
thiểu (minimum) phải từ 0 trở lên.
Hình
42
Đối
với trường hợp của Hourly pay rate,
ta lồng <f:validateDoubleRange>
vào <h:inputText>
và qui định rằng lương một giờ phải từ 6.00 USD trở
lên.
Hình
43
Khi user
nhập data vô nghĩa, chẳng hạn abc,
application sẽ tự động phát ra một thông báo lỗi. Nếu
muốn thay đổi nội dung của thông báo lỗi, ta có thể
thêm converterMessage attribute
vào <h:inputText>.
Hình
44
7.
Xóa form ở phía browser bằng JavaScript
Bây giờ hãy thi
hành application, rồi nhập vào một giá trị cho Number
of hours worked, chẳng hạn
10. Nhưng giả định rằng thật sự thì ta muốn nhập 40,
chứ không phải 10. Ta muốn xóa hết để nhập lại từ
đầu bằng việc click Clear
button. Nhưng sau khi click, data không được xóa mà thay vào
đó là yêu cầu không được để trống ô Hourly
pay rate! Dĩ nhiên đây là
kết quả không mong muốn. Để
bỏ qua giai đoạn kiểm tra tính hợp lệ của data (data
validation) khi user clicks Clear
button, ta bổ sung attribute immediate=”true”.
Đến
đây khi thi hành application, nhập 10 cho Number of
hours worked, rồi click Clear,
ta không còn nhận được thông báo lỗi nữa, nhưng số
10 vẫn không được xóa! Thật ra thì giá trị đó đã
được xóa ở phía server thông quan clear(),
nhưng chưa được xóa ở phía browser.
Để
xử lý tình huống này, ta bổ sung một hàm (function) viết
bằng ngôn ngữ JavaScript.
Right-click Web
Pages,
chọn New,
rồi chọn Other...
để chuyển sang New
File
window.
Chọn
Other
ở mục bên trái, chọn tiếp JavaScript
File
ở mục bên phải, rồi click Next
để chuyển sang bước đặt tên và xác định vị trí
file.
Nhập
clearInputTexts
vào ô File
Name:,
và nhập web/resources
vào
ô Folder:,
rồi click Finish.
Nhập đoạn code
sau rồi nhấn Ctrl+S để
lưu.
function clearInputTexts(form) { inputs = form.getElementsByTagName('input'); for (i = 0; i < inputs.length; i++) if (inputs[i].type == 'text') inputs[i].value = ''; }
Trong
index.xhtml, ta khai
báo JavaScript function ở trên bằng cách bổ sung <script>
tag.
Và cuối cùng, ta bổ
sung attribute onclick
với lệnh gọi JavaScript function.
III.
Tổng kết
Bài viết đã
trình bày các bước chính khi phát triển một web
application với JSF:
- Thiết kế một UI screen tĩnh dùng ngôn ngữ XHTML.
- Bổ sung phần tương tác giữa user và application bằng một managed bean. Thay thế các thành phần tương tác XHTML bằng JSF tags.
- Phát triển phần tính toán của application, độc lập với phần tương tác với user, sau đó kết nối với UI screen thông qua managed bean.
- Đảm bảo user nhập data theo đúng yêu cầu.
- Xóa form ở phía browser bằng JavaScript.
IV.
Tài liệu tham khảo
- Gaddis T. (2010) Starting Out with Java From Control Structures Through Objects (4th edition), Pearson Education, Boston. Chương 1 và 2.
- Gibson A. (2010) Getting Started with Contexts and Dependency Injection and JSF 2.0, <http://netbeans.org/kb/docs/javaee/cdi-intro.html> (14 June 2010).
- Eric Jendrock, Ian Evans, Devika Gollapudi, Kim Haase, Chinmayee Srivathsa (2011) The Java EE 6 Tutorial, Basic Concepts, Fourth Edition, Addison-Wesley. Chapter 17.
- Tong K. K. I. (2009) Beginning JSFTM APIs and JBoss® Seam, Apress, New York. Chapters 1, 2, and 3.
- David R. Heffelfinger (2011) Java EE 6 Development with NetBeans 7, Packt Publishing. Chapter 4.
- Clear a form with JavaScript. http://www.electrictoolbox.com/javascript-clear-form/
V.
Thuật ngữ tiếng Anh
annotation
|
phụ
chú
|
application
|
ứng
dụng
|
attribute
|
thuộc
tính
|
backing
bean
|
đối
tượng đứng phía sau, hỗ trợ cho trang .xhtml
|
browser
|
trình
duyệt web
|
business
logic
|
phần
tính toán của một ứng dụng
|
business
logic tier
|
tầng
tính toán của một ứng dụng
|
button
|
nút
lệnh
|
click
|
kích
nút chuột trái
|
code
|
mã
lệnh
|
computer
|
máy
tính
|
constructor
|
phương
thức tạo đối tượng
|
converter
|
bộ
chuyển đổi dữ liệu
|
data
|
dữ
liệu
|
deploy
|
triển
khai
|
download
|
tải
|
field
|
trường
|
form
|
thành
phần tương tác với người dùng
|
function
|
hàm
|
IDE
|
xem
Integrated Development Environment
|
install
|
cài
đặt
|
Integrated
Development Environment
|
môi
trường phát triển tích hợp
|
JSF
|
JavaServer
Faces
|
label
|
nhãn
|
managed
bean
|
tạm
xem backing bean
|
margin
|
lề
|
message
|
thông
báo, thông điệp
|
method
|
phương
thức
|
model
tier
|
tầng
tính toán của một ứng dụng
|
no-arg
constructor
|
phương
thức tạo đối tượng phi tham biến
|
Object-Oriented
Programming
|
Lập
trình Hướng Đối tượng
|
OOP
|
xem
Object-Oriented Programming
|
package
|
gói
|
pixel
|
điểm
ảnh
|
presentation
|
phần
giao tiếp với người dùng của một ứng dụng
|
primitive
data type
|
kiểu
dữ liệu nguyên thủy
|
project
|
dự
án
|
reuse
|
tái
dụng
|
right-click
|
kích
nút chuột phải
|
static
|
tĩnh
|
tag
|
thẻ
|
UI
component
|
thành
phần giao diện với người dùng
|
UI
screen
|
màn
hình giao diện
|
unit
test
|
kiểm
thử đơn vị
|
user
|
người
dùng
|
user
interface
|
phần
giao diện với người dùng
|
validator
|
bộ
kiểm tra tính hợp lệ của dữ liệu
|
window
|
cửa
sổ
|
VI.
Phụ lục. Hướng
dẫn tải và cài đặt NetBeans
IDE
Trước khi cài
đặt NetBeans IDE, computer cần cài sẵn một phiên bản
Java SE Development Kit (JDK).
Download
phiên bản NetBeans mới nhất tại
http://netbeans.org/downloads/index.html.
Cần chọn cột
Java
EE
hoặc All.
Sau khi đã
download xong, ta chỉ cần double-click vào file vừa download
và làm theo chỉ dẫn để cài đặt NetBeans vào computer.
Không có nhận xét nào:
Đăng nhận xét