You are on page 1of 20

9/10/2011

1
LẬP TRÌNH WEB HƯỚNG JAVA
Bài 19: Cơ bản về Struts
Giảng viên: ThS. Trịnh Tuấn Đạt
Bộ môn CNPM
Email: trinhtuandat.bk@gmail.com/dattt@soict.hut.edu.vn
Bộ môn Công nghệ Phần mềm
Viện CNTT & TT
Trường Đại học Bách Khoa Hà Nội
1 DatTT-DSE-SOICT-HUST
Nội dung
 1. Struts là gì, tại sao sử dụng Struts?
 2. Kiến trúc của Struts
 Controller
 Model
 View
 3. web.xml
 4. Internationalization
 5. Input Validation
 6. Xử lý lỗi
 7. Chọn View trả về
2 DatTT-DSE-SOICT-HUST
1.1. Struts là gì?
3 DatTT-DSE-SOICT-HUST
Jakarta Struts
 Struts là một Web application framework mã
nguồn mở, là một phần của Apache Jakarta
project
 http://jakarta.apache.org/struts/
4 DatTT-DSE-SOICT-HUST
1.1. Struts là gì?
 Model-View-Controller (MVC) framework
 Được sử dụng để xây dựng các ứng dụng Web sử
dụng Servlets và JSPs
 Ứng dụng Struts là ứng dụng Web, chạy được trên bất kỳ
Sevlet container nào, bao gồm cả tất cả các J2EE
compliant App servers
 Tuân theo các mẫu thiết kế
 Singleton, composition view, delegate
 Dễ học & sử dụng
 Có kèm các thư viện thẻ JSP custom tag
5 DatTT-DSE-SOICT-HUST
Struts cho phép các LTV ...
 Phát triển ứng dụng web JSP/Servlet theo
mô hình MVC
 Sử dụng các đối tượng có sẵn của framework
trong file cấu hình XML
 Sử dụng các mẫu thiết kế xây dựng sẵn của
framework
 Sử dụng các đặc tính nâng cao như input
validation, internationalization
6 DatTT-DSE-SOICT-HUST
9/10/2011
2
1.2. Tại sao sử dụng Struts
7 DatTT-DSE-SOICT-HUST
1.2. Tại sao sử dụng Struts?
 Struts đã đảm nhiệm những phần phức tạp nhất khi
xây dựng ứng dụng MVC
 Dễ học và sử dụng
 Nhiều tính năng
 Nhiều công cụ hỗ trợ của bên thứ 3 (third party
tools)
 Linh động và dễ mở rộng (Flexible & extensible)
 Cộng đồng sử dụng đông đảo
 Ổn định và vẫn đang liên tục phát triển
 Mã nguồn mở
8 DatTT-DSE-SOICT-HUST
1.2. Tại sao sử dụng Struts?
 Tích hợp tốt với Java EE (J2EE)
 Hỗ trợ taglib tốt
 Xử lý lỗi thống nhất, theo cả 2 cơ chế
programmatic và declarative
 Tích hợp với Tiles framework (Struts nâng
cao)
9 DatTT-DSE-SOICT-HUST
2. Kiến trúc của Struts
10 DatTT-DSE-SOICT-HUST
Model-View-Control (model 2)
Request
1
(Controller)
Servlet
(View)
JSP Response
5
3
4
B
R
O
W
S
E
R
Servlet Container (EIS)
Redirect
2
(Model)
Java Bean
MVC Design Pattern
11 DatTT-DSE-SOICT-HUST
Struts hoạt động như thế nào
12 DatTT-DSE-SOICT-HUST
9/10/2011
3
Struts: Kiến trúc MVC
 Controller trung tâm điều hành luồng ứng dụng, ủy
quyền cho các bộ xử lý thích hợp gọi là Action
 Action Handlers có thể sử dụng các model
components
 Model đóng gói trạng thái hoặc logic nghiệp vụ
 Điều khiển được chuyển tiếp (forward) cho
Controller với View phù hợp
 Việc forward có thể được xác định bằng việc tra cứu từ
tập các mappings trong file cấu hình, cho phép tăng độ
linh động gữa tầng View và Model
13 DatTT-DSE-SOICT-HUST
Struts: Kiến trúc MVC
 3 thành phần chính trong Struts
 Servlet controller (Controller)
 Java Server Pages hoặc bất kỳ công nghệ hiển
thị nào khác (View)
 Application Business Logic ở dạng bất kỳ phù hợp
với ứng dụng (Model)
 Struts tập trung chủ yếu vào phần Controller
 Struts có sự độc lập giữa Model & View
 Struts có thể sử dụng bất kỳ công nghệ Model &
View nào
14 DatTT-DSE-SOICT-HUST
Struts: Kiến trúc MVC
 File cấu hình chứa các action mappings
 Ánh xạ URL với các Action
 Controller sử dụng các mapping này để trả về
HTTP requests cho Action nào của ứng dụng
 Xác định forwarding/navigation
 Mapping phải mô tả được
 Đường dẫn của yêu cầu: request path
 Action xử lý request nhận được
15 DatTT-DSE-SOICT-HUST
2.1. Controller
16 DatTT-DSE-SOICT-HUST
Controller có nhiệm vụ gì?
 Giống như 1 switch trong kiến trúc MVC
 Tất cả các request phải đi qua controller
 Chịu trách nhiệm điều khiển luồng cho các
xử lý request (action mapping)
 Đọc file cấu hình để xác định luồng điều khiển
17 DatTT-DSE-SOICT-HUST
Các thành phần Controller
18 DatTT-DSE-SOICT-HUST
9/10/2011
4
Controller trong Struts Framework
 Struts framework cung cấp servlet:
 org.apache.struts.action.ActionServlet
 Phải cấu hình Servlet mapping cho servlet này
trong file web.xml
 Các cấu hình liên quan tới Struts khác được
tạo lập trong file struts-config.xml
 Action Mapping định nghĩa các ánh xạ giữa URI
của request gửi đến với 1 lớp Action cụ thể
19 DatTT-DSE-SOICT-HUST
Nhiệm vụ của LTV
 Viết lớp Action (kề thừa lớp Action) cho mỗi
request có thể nhận được
 Phải override phương thức execute() (phương
thức perform() trong Struts 1.0)
 Viết action mapping trong file cấu hình
 struts-config.xml
 Cập nhật file web.xml, thực hiện mapping
cho ActionServlet
 web.xml
20 DatTT-DSE-SOICT-HUST
Các thành phần Controller trong Struts
Framework
 ActionServlet (Struts cung cấp)
 RequestProcessor (Struts 1.1) (Struts cung cấp)
 Cho mỗi module
 Action (LTV viết)
 LTV kế thừa lớp Action do Struts cung cấp
 Action Mapping (Tạo bởi LTV)
 LTV tạo các action mapping trong file struts-config.xml
 Struts framework sẽ tạo các đối tượng ActionMapping và
truyền chúng cho đối tượng Action
21 DatTT-DSE-SOICT-HUST
2.1.1. ActionServlet
(Framework cung cấp)
22 DatTT-DSE-SOICT-HUST
Nhiệm vụ của ActionServlet?
 Thực hiện vai trò của Controller
 Xử lý các user requests
 Xác định xem user cần gì, căn cứ ào request
nhận được
 Lấy dữ liệu từ model (nếu cần thiết), và
 Lấy ra view phù hợp trả về cho người dùng
 Ủy nhiệm hầu hết những công việc này cho
lớp Action
23 DatTT-DSE-SOICT-HUST
Nhiệm vụ của ActionServlet? (2)
 Chịu trách nhiệm khởi tạo và dọn dẹp tài
nguyên
 loads các cấu hình ứng dụng trong web.xml
 Duyệt lần lượt các goes through an enumeration
of all init-param elements, looking for those
elements who's name starts with config/ for
modules
 Để truy cập vào module foo, sử dụng URL như:
 http://localhost:8080/myApp/foo/someAction.do
24 DatTT-DSE-SOICT-HUST
9/10/2011
5
Điều khiển luồng bởi Controller
25 DatTT-DSE-SOICT-HUST
Luồng Struts (Struts 1.0)
Http://myhost/authorize.do
Server configured to pass *.do extensions to
org.apache.struts.action.ActionServlet via a
web.xml configuration file
ActionServlet object inspects the URI and tries to match it
against an ActionMapping located in the struts-config.xml file
Instance of appropriate Action class is found and it’s execute()
is called.
Action object handles the request and returns a next view.
View is identified by ActionForward objerct.
26 DatTT-DSE-SOICT-HUST
2.1.2. RequestProcessor
(Framework cung cấp)
27 DatTT-DSE-SOICT-HUST
Nhiệm vụ của RequestProcessor?
 processPath
 Xác định đường dẫn (path) được request. Sau đó sẽ được
sử dụng để lấy về một ActionMapping.
 processLocale
 Chọn một locale (nếu chưa chọn locale nào) và đặt nó
vào trong request.
 processContent
 Thiết lập content type mặc định (tùy chọn cách encoding)
cho tất cả các response nếu được yêu cầu
28 DatTT-DSE-SOICT-HUST
What Does RequestProcessor Do?
 processMapping
 Xác định ActionMapping ứng với đường dẫn yêu cầu.
 processRoles
 Nếu mapping được kết hợp với một role, cần đảm bảo
user có role tương ứng đó. Nếu không, tạo ra một error
và dừng xử lý request.
 processActionForm
 Tạo một thực thể ActionForm (nếu cần thiết) kết hợp với
mapping trên (nếu có), với tầm vực (scope) phù hợp
29 DatTT-DSE-SOICT-HUST
What Does RequestProcessor Do?
 processPopulate
 Gắn ActionForm với request, nếu có
 processValidate
 Thực hiện validate (nếu được yêu cầu) trên
ActionForm gắn với request này (nếu có).
 processForward
 Nếu mapping biểu diễn một forward, forward
đến đường dẫn được chỉ định trong mapping.
30 DatTT-DSE-SOICT-HUST
9/10/2011
6
What Does RequestProcessor Do?
 processInclude
 Nếu mapping biểu diễn một include, include kết
quả của việc gọi đến đường dẫn (path) trong
request này
 processActionCreate
 Tạo một thực thể của lớp được đặc tả trong
ActionMapping đang xét (nếu cần).
 processActionPerform
 Là lúc mà phương thức perform() hoặc execute()
sẽ được gọi
31 DatTT-DSE-SOICT-HUST
What Does RequestProcessor Do?
 processForwardConfig
 Cuối cùng, phương thức xử lý của
RequestProcessor lấy về ActionForward trả về từ
lớp Action, và sử dụng nó để chọn ra resource
tiếp theo (nếu có).
 Thường ActionForward sẽ dẫn đến các trang
trình diễn (presentation page), sinh ra response
trả về cho client.
32 DatTT-DSE-SOICT-HUST
2.1.3. Action Mapping
(LTV viết)
33 DatTT-DSE-SOICT-HUST
Action Mapping trong file cấu hình Struts
 Struts controller ActionServlet cần biết 1 số
thông tin để map mỗi request URI gửi đến
với lớp Action phù hợp
 Các yêu cầu này được đóng gói trong một
Java interface là ActionMapping
 Struts framework sẽ tạo đối tượng
ActionMapping cho mỗi phần tử cấu hình
<ActionMapping> trong file struts-config.xml
34 DatTT-DSE-SOICT-HUST
Struts Config File (struts-config.xml)
 struts-config.xml chứa 3 phần tử quan trọng
để mô tả các actions:
 <form-beans> chứa các định nghĩa FormBean
bao gồm tên và kiểu (classname)
 <action-mapping> chứa các định nghĩa action
 Sử dụng một phần tử <action> cho mỗi action được
định nghĩa
 <global-forwards> chứa cá định nghĩa global
forward
35 DatTT-DSE-SOICT-HUST
Struts Config File (struts-config.xml)
 <form-beans>
 Phần tử này chứa các định nghĩa form bean.
 Sử dụng phần tử <form-bean> cho mỗi form
bean, bao gồm 2 thuộc tính quan trọng sau:
 name: the name of the request request (and session
level attribute that this form bean will be stored as)
 type: tên lớp đầy đủ của form bean
36 DatTT-DSE-SOICT-HUST
9/10/2011
7
struts-config.xml: <form-beans>
1.<?xml version="1.0" encoding="ISO-8859-1" ?>
2.<!DOCTYPE struts-config PUBLIC
3. "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
4. "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
5.<struts-config>
6. <!-- ========== Form Bean Definitions ================= -->
7. <form-beans>
8. <form-bean name="submitForm"
9. type="submit.SubmitForm"/>
10. </form-beans>
37 DatTT-DSE-SOICT-HUST
Struts Config File (struts-config.xml)
 <action-mappings>
 Phần tử này chứa các định nghĩa action. Mỗi
action cần định nghĩa ứng với một phần tử
<action>
38 DatTT-DSE-SOICT-HUST
Struts Config File (struts-config.xml)
 <action-mappings>
 Mỗi phần tử <action> cần định nghĩa các thuộc
tính sau:
 path: Đường dẫn tới action (tương đối so với context
của ứng dụng) (URI của request)
 type: Tên đầy đủ của lớp Action
 name: Tên của phần tử <form-bean> sử dụng với
action này
 input: Tên của trang hiển thị khi có lỗi validate input
form
 scope: Tầm vực của form bean được tạo
 validate: Có thực hiện validate input form hay không 39 DatTT-DSE-SOICT-HUST
struts-config.xml: <action-mappings>
1.<!-- ========== Action Mapping Definitions ============ -->
2. <action-mappings>
3. <action path="/submit"
4. type="submit.SubmitAction"
5. name="submitForm"
6. input="/submit.jsp"
7. scope="request"
8. validate="true">
9. <forward name="success" path="/submit.jsp"/>
10. <forward name="failure" path="/submit.jsp"/>
11. </action>
12. </action-mappings>
13.</struts-config>
40 DatTT-DSE-SOICT-HUST
struts-config.xml: <action-mappings>
1. <action-mappings>
2. <action
3. path="/logon"
4. type="org.apache.struts.webapp.example.LogonAction"
5. name="logonForm"
6. scope="request"
7. input="/logon.jsp"
8. validate="true" />
9. </action-mappings>
10.</struts-config>
41 DatTT-DSE-SOICT-HUST
Action Mapping Config File
 <global-forwards>
 Forwards là các thực thể của lớp ActionForward
được trả về từ phương thức execute() của lớp
Action
 Thực hiện map các logical names với các
resources cụ thể (thường là các trang JSPs)
 Phần tử <forward> có các thuộc tính sau
 name: logical name của forward
 Được sử dụng trong phương thức execute() của lớp Action để
forward đến tài nguyên tiếp theo
 path: resource sẽ được forward đến
 redirect: redirect (true) hay forward (false)
42 DatTT-DSE-SOICT-HUST
9/10/2011
8
Global Forwarding
1.<struts-config>
2. <form-beans>
3. <form-bean
4. name="logonForm"
5. type="org.apache.struts.webapp.example.LogonForm" />
6. </form-beans>
7. <global-forwards
8. type="org.apache.struts.action.ActionForward">
9. <forward
10. name="logon"
11. path="/logon.jsp"
12. redirect="false" />
13. </global-forwards>
14.
43 DatTT-DSE-SOICT-HUST
Local Forwarding
1.<!-- Edit mail subscription -->
2.<action
3. path="/editSubscription"
4. type="org.apache.struts.webapp.example.EditSubscriptionAction"
5. name="subscriptionForm"
6. scope="request"
7. validate="false">
8. <forward
9. name="failure"
10. path="/mainMenu.jsp"/>
11. <forward
12. name="success"
13. path="/subscription.jsp"/>
14.</action>
44 DatTT-DSE-SOICT-HUST
2.1.4. ActionForm
(LTV phải cung cấp, nếu không sử
dụng DynaActionForm)
45 DatTT-DSE-SOICT-HUST
ActionForm Bean (Form bean)
 Viết bởi LTV
 Định nghĩa một ActionForm bean (bản chất là 1 lớp Java
kế thừa lớp ActionForm) cho input form
 Định nghĩa trong file struts-config.xml
 <form-bean>
 Tên thuọc tính của lớp <Action>
 Chỉ chứa các phương thức getter & setter cho các
thuộc tính (không có xử lý nghiệp vụ)
 Cung cấp cơ chế validation chuẩn tắc
46 DatTT-DSE-SOICT-HUST
ActionForm Bean & Controller
 Với mỗi ActionForm bean được định nghĩa trong file
servlet-config.xml, Controller (ActionServlet) sẽ
 Kiểm tra session scope cho 1 thực thể của ActionForm
bean
 Nếu không tồn tại, controller sẽ tạo mới một thực thể
 Gọi phương thức setter tương ứng của ActionForm bean
cho tất cả các tham số request có tên trùng với tên của
thuộc tính của bean
 Truyền đối tượng ActionForm bean làm tham số của
phương thức execute() của lớp Action
47 DatTT-DSE-SOICT-HUST
Viết một ActionForm Bean?
 Chỉ cần viết phương thức getter và setter cho
mỗi thuộc tính của một input form
 Không có bất kỳ đoạn code xử lý nghiệp vụ nào
 Thêm 1 phương thức validate chuẩn tắc:
validate()
 Controller sẽ gọi đến phương thức này
 Định nghĩa một thuộc tính (cùng với phương
thức getXxx và setXxx) cho mỗi trường xuất
hiện trong input form
48 DatTT-DSE-SOICT-HUST
9/10/2011
9
V
í

d

:

s
u
b
m
i
t
.
j
s
p
1.<%@ page language="java" %>
2.<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
3.<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
4.<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
5.<html>
6.<head><title>Submit example</title></head>
7.<body>
8.<h3>Example Submit Page</h3>
9.<html:errors/>
10.<html:form action="submit.do">
11.Last Name: <html:text property="lastName"/><br>
12.Address: <html:textarea property="address"/><br>
13.Sex: <html:radio property="sex" value="M"/>Male
14. <html:radio property="sex" value="F"/>Female<br>
15.Married: <html:checkbox property="married"/><br>
16.Age: <html:select property="age">
17. <html:option value="a">0-19</html:option>
18. <html:option value="b">20-49</html:option>
19. <html:option value="c">50-</html:option>
20. </html:select><br>
21. <html:submit/>
22.</html:form>
49 DatTT-DSE-SOICT-HUST
Model: ActionForm
1.package submit;
2.import javax.servlet.http.HttpServletRequest;
3.import org.apache.struts.action.*;
4.public final class SubmitForm extends ActionForm {
5. /* Last Name */
6. private String lastName = "Hansen"; // default value
7. public String getLastName() {
8. return (this.lastName);
9. }
10. public void setLastName(String lastName) {
11. this.lastName = lastName;
12. }
13. /* Address */
14. private String address = null;
15. public String getAddress() {
16. return (this.address);
17. }
18. public void setAddress(String address) {
19. this.address = address;
20. }
21....
50 DatTT-DSE-SOICT-HUST
struts-config.xml: <form-beans>
1.<?xml version="1.0" encoding="ISO-8859-1" ?>
2.<!DOCTYPE struts-config PUBLIC
3. "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
4. "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
5.<struts-config>
6. <!-- ========== Form Bean Definitions ================= -->
7. <form-beans>
8. <form-bean name="submitForm"
9. type="submit.SubmitForm"/>
10. </form-beans>
51 DatTT-DSE-SOICT-HUST
struts-config.xml: <action-mappings>
1.<!-- ========== Action Mapping Definitions ============ -->
2. <action-mappings>
3. <action path="/submit"
4. type="submit.SubmitAction"
5. name="submitForm"
6. input="/submit.jsp"
7. scope="request"
8. validate="true">
9. <forward name="success" path="/submit.jsp"/>
10. <forward name="failure" path="/submit.jsp"/>
11. </action>
12. </action-mappings>
13.</struts-config>
52 DatTT-DSE-SOICT-HUST
DynaActionForm trong Struts 1.1
 Thay vì tạo một lớp con cho ActionForm với
các phương thức get/set cho mỗi thuộc tính
của bean, LTV có thể liệt kê các thuộc tính
này, cùng với kiểu, giá trị mặc định trong file
cấu hình Struts
 NÊN sử dụng DanaActionForm khi có thể
(Struts nâng cao)
53 DatTT-DSE-SOICT-HUST
2.1.5. Action
(LTV tự viết)
54 DatTT-DSE-SOICT-HUST
9/10/2011
10
Action Class Diagram
55 DatTT-DSE-SOICT-HUST
Lớp Action
 Tập trung vào luồng điều khiển
 Xử lý client request bằng cách gọi cách đối tượng khác
(BusinessLogic beans) trong phương thức execute() của

 Trả về một đối tượng ActionForward định danh một
destination resource mà điều khiển sẽ được forward đến
 Destination resource có thể là
 JSP
 Tile definition
 Velocity template
 Action khác
56 DatTT-DSE-SOICT-HUST
Lớp Action là gì?
 Lớp Java thực hiện các “công việc” trong ứng dụng
 Xử lý request
 Thực hiện các xử lý logic nghiệp vụ
 Có thể đơn giản hoặc phức tạp
 Lớp action đơn giản tự thực hiện xử lý logic nghiệp vụ
 Lớp action phức tạp ủy quyền các xử lý logic nghiệp vụ
cho các thành phần Model
 Chức năng của lớp Action giống như mẫu thiết kế Facade
57 DatTT-DSE-SOICT-HUST
Ví dụ Action: Logon
 Ứng dụng cần
 Xác thực người dùng
 Thiết lập User Session
 Xử lý lỗi
 Cần viết code lớp “LogonAction”
58 DatTT-DSE-SOICT-HUST
Nhiệm vụ của LTV: Action Class
 Kế thừa org.jakarta.struts.action.Action
 Override
 Phương thức execute() (trong Struts 1.1)
 Phương thức perform() (trong Struts 1.0)
59 DatTT-DSE-SOICT-HUST
Phương thức execute(..) của lớp Action
(Chỉ trong Struts 1.1)
 Được gọi bởi controller
public ActionForward execute(
ActionMapping mapping,
ActionFormform,
HttpServletRequest request,
HttpServletResponse response)
throws Exception;
60 DatTT-DSE-SOICT-HUST
9/10/2011
11
Phương thức perform(..) của lớp Action
(Chỉ trong Struts 1.0)
 Deprecated
public ActionForward perform(
ActionMapping mapping,
ActionFormform,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException;
61 DatTT-DSE-SOICT-HUST
Phương thức execute() của lớp Action
 Thực hiện các xử lý cần thiết với request
 Cập nhật các đối tượng phía server (Scope
variables) được sử dụng để tạo trang trả về
cho người dùng
 Trả về đối tượng ActionForward phù hợp
62 DatTT-DSE-SOICT-HUST
Ví dụ: lớp Action
1.package submit;
2.import javax.servlet.http.*;
3.import org.apache.struts.action.*;
4.public final class SubmitAction extends Action {
5. public ActionForward execute(ActionMapping mapping,
6. ActionForm form,
7. HttpServletRequest request,
8. HttpServletResponse response) {
9. SubmitForm f = (SubmitForm) form; // get the form bean
10. // and take the last name value
11. String lastName = f.getLastName();
12. // Translate the name to upper case
13. //and save it in the request object
14. request.setAttribute("lastName", lastName.toUpperCase());
15.
16. // Forward control to the specified success target
17. return (mapping.findForward("success"));
18. }
19.}
63 DatTT-DSE-SOICT-HUST
Hướng dẫn thiết kế lớp Action
 Controller Servlet tạo 1 thực thể duy nhất
cho lớp Action, và sử dụng nó cho tất cả các
request
 Lớp Action phải hoạt động ở chế độ multi-
threaded safe
 Chỉ sử dụng các biến local (as opposed to
instanace variables)
 Chỉ nên tạo các lớp Action đơn giản
 Sử dụng các thành phần Model cho các xử lý
logic nghiệp vụ phức tạp
64 DatTT-DSE-SOICT-HUST
Ví dụ 2: Lớp Action
1.package submit;
2.import javax.servlet.http.*;
3.import org.apache.struts.action.*;
4.public final class SubmitAction extends Action {
5. public ActionForward execute(ActionMapping mapping,
6. ActionForm form,
7. HttpServletRequest request,
8. HttpServletResponse response) {
9. SubmitForm f = (SubmitForm) form; // get the form bean
10. // and take the last name value
11. String lastName = f.getLastName();
12. if (lastName.startsWith(“Passion”)){
13. // Translate the name to upper case
14. //and save it in the request object
15. request.setAttribute("lastName", lastName.toUpperCase());
16. // Forward control to the specified success target
17. return (mapping.findForward("success"));
18. }
19. else{
20. return (mapping.findForward("failure"));
21. }
22. }
23.}
65 DatTT-DSE-SOICT-HUST
struts-config.xml: ActionMapping
1. <!-- ========== Action Mapping Definitions ============ -->
2. <action-mappings>
3. <action path="/submit"
4. type="submit.SubmitAction"
5. name="submitForm"
6. input="/submit.jsp"
7. scope="request"
8. validate="true">
9. <forward name="success" path="/submitSuccess.jsp"/>
10. <forward name="failure" path="/submitFailure.jsp"/>
11. </action>
12. </action-mappings>
13.</struts-config>
66 DatTT-DSE-SOICT-HUST
9/10/2011
12
Các lớp Action xây dựng sẵn
 ForwardAction
 DispatchAction
(Advanced Struts)
67 DatTT-DSE-SOICT-HUST
2.2. Các thành phần Model
(Model Components)
(LTV viết)
68 DatTT-DSE-SOICT-HUST
Model Components
 Model được chia thành:
 Internal state của hệ thống
 Business logic thay đổi các trạng thái đó
 Internal state của hệ thống được biểu diễn bằng:
 JavaBeans
 Enterprise JavaBeans
 POJO's
 JDO
 JDBC
 ...
69 DatTT-DSE-SOICT-HUST
Model components
70 DatTT-DSE-SOICT-HUST
Model Components
 JavaBeans và Scope
 Page – chỉ thấy trong 1 trang JSP, trong vòng đời
của request hiện tại
 Request – chỉ thấy trong 1 trang JSP, cũng như
bất kỳ trang hoặc servlet nào được included
trong trang JSP này, hoặc được forwarded từ nó
 Session – thấy được cho tất cả các trang JSP và
các servlet trong session của 1 user, trên 1 hoặc
nhiều requests
 Application – thấy được cho tất cả các trang JSP
và các servlets trong ứng dụng web
71 DatTT-DSE-SOICT-HUST
Model Components
 Các trang JSP và servlets trong cùng 1 ứng
dụng web chia sẻ cùng 1 tập các bean
 Ví dụ
 Servlet code
MyCart mycart = new MyCart(...);
request.setAttribute("cart", mycart);
 JSP page
<jsp:useBean id="cart" scope="request"
class="com.mycompany.MyApp.MyCart"/>
72 DatTT-DSE-SOICT-HUST
9/10/2011
13
Các thành phần Model trong Struts
Framework
 ActionForm Bean
 Lưu ý ActionForm Bean là một Model component,
mặc dù nó chỉ biểu diễn dữ liệu nhập bởi người
dùng
 SystemState Bean
 Chỉ là thuật ngữ mức khái niệm: Struts không
cung cấp các API lập trình
 BusinessLogic Bean
 Chỉ là thuật ngữ mức khái niệm: Struts không
cung cấp các API lập trình
73 DatTT-DSE-SOICT-HUST
Struts Model Components
System State Bean & Business
logic Bean
74 DatTT-DSE-SOICT-HUST
System State Bean
 Struts không định nghĩa lớp chuẩn cho loại bean
này
 Xác định trạng thái hiện tại
 Có thể được biểu diễn bởi tập một hoặc nhiều các lớp
JavaBeans, các lớp có các thuộc tính xác định trạng thái
hiện tại
 Ví dụ: hệ thống giỏ hàng-shopping cart:
 Chứa một bean tượng trưng cho giỏ hàng được quản lý
độc lập cho mỗi người mua hàng
 Bao gồm tập các items mà người mua hàng đã chọn mua
75 DatTT-DSE-SOICT-HUST
System State Bean
 Với hệ thống quy mô nhỏ, hoặ với các thông tin
trạng thái (state information) không cần lưu trữ lâu
dài:
 Tập các system state beans có thể chứa toàn bộ tri thức
hệ thống có được
 Với ứng dụng quy mô lớn
 Các System state beans có thể biểu diễn thông tin được
lưu trữ lâu dài trong các CSDL ngoài
 Ví dụ: đối tượng CustomerBean tương ứng với 1 row nào đó
trong bảng CUSTOMERS
 Có thể sử dụng EJB
76 DatTT-DSE-SOICT-HUST
BusinessLogic Bean
 Struts không định nghĩa lớp chuẩn cho loại
bean này
 Có thể là một JavaBean thông thường
 Có thể là EJB có trạng thái hoặc phi trạng thái
 Đóng gói các functional logic (làm thay đổi
trạng thái hệ thống) thành các phương thức
 Hệ thống lớn: phương thức nằm luôn trong các
beans biểu diễn trạng thái hệ thống
 Hệ thống nhỏ: phương thức nằm trong các lớp
Action
77 DatTT-DSE-SOICT-HUST
BuesinessLogic Bean
 Lý tưởng nhất là phải được thiết kế sao cho
chúng không biết mình được thực thi trên
môi trường Web
 Không nên tham chiếu đến bất kỳ đối tượng nào
trong ứng dụng Web
 Tăng tính tái sử dụng
78 DatTT-DSE-SOICT-HUST
9/10/2011
14
2.3. Các thành phần View
(View Components)
LTV phải cung cấp
79 DatTT-DSE-SOICT-HUST
View components
80 DatTT-DSE-SOICT-HUST
View Components
 Các JSP files cho từng ứng dụng
 Tập các JSP custom tag libraries
 Các Resource files cho tính năng
internationalization
 Cho phép nhanh chóng tạo form cho các ứng
dụng
 Phối hợp hoạt động với controller Servlet
81 DatTT-DSE-SOICT-HUST
View
 Đối tượng ActionForward thông báo với
Servlet controller trang JSP nào sẽ được trả
về (dispatched)
 Các trang JSP sử dụng ActionForm để lấy dữ
liệu output từ Model để hiển thị
 Struts có tập các thư viện thẻ (tag libraries)
 Dễ phát triển các nội dung động
 Đơn giản trao đổi giữa HTML designer và LTV
82 DatTT-DSE-SOICT-HUST
Forms và FormBean Interactions
 Nếu user gây lỗi (vd: nhập liệu), ứng dụng
cần cho phép họ sửa đổi lại giá trị cũ
 Với JSP:
 <input type="text" name="username"
 value="<%= loginBean.getUsername() >"/>
 Với Struts, chỉ cần
 <html:text property="username"/>;
83 DatTT-DSE-SOICT-HUST
Ví dụ: submit.jsp
1.<%@ page language="java" %>
2.<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
3.<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
4.<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
5.<html>
6.<head><title>Submit example</title></head>
7.<body>
8.<h3>Example Submit Page</h3>
9.<html:errors/>
10.<html:form action="submit.do">
11.Last Name: <html:text property="lastName"/><br>
12.Address: <html:textarea property="address"/><br>
13.Sex: <html:radio property="sex" value="M"/>Male
14. <html:radio property="sex" value="F"/>Female<br>
15.Married: <html:checkbox property="married"/><br>
16.Age: <html:select property="age">
17. <html:option value="a">0-19</html:option>
18. <html:option value="b">20-49</html:option>
19. <html:option value="c">50-</html:option>
20. </html:select><br>
21. <html:submit/>
22.</html:form>
84 DatTT-DSE-SOICT-HUST
9/10/2011
15
Ví dụ: submit.jsp
1.<logic:present name="lastName" scope="request">
2.Hello
3.<logic:equal name="submitForm" property="age" value="a">
4. young
5.</logic:equal>
6.<logic:equal name="submitForm" property="age" value="c">
7. old
8.</logic:equal>
9.<bean:write name="lastName" scope="request"/>
10.</logic:present>
11.</body>
12.</html>
85 DatTT-DSE-SOICT-HUST
3. web.xml
86 DatTT-DSE-SOICT-HUST
Web App Deployment Descriptor
(web.xml)
 Ứng dụng Struts là một ứng dụng Web
 Tuân thủ theo luật chung
 Phải có file deployment descriptor - web.xml
 web.xml chứa:
 Cấu hình mapping cho ActionServlet
 Định nghĩa Resource file trong <init-param>
 Chỉ định file servlet-config.xml trong <init-param>
 Định nghĩa các thư viện thẻ Struts
 web.xml được lưu trữ trong WEB-INF/web.xml
87 DatTT-DSE-SOICT-HUST
Ví dụ: web.xml
1.<!DOCTYPE web-app
2. PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
3. "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
4.<web-app>
5. <display-name>Advanced J2EE Programming Class Sample App</display-name>
6.
7. <!-- Standard Action Servlet Configuration (with debugging) -->
8. <servlet>
9. <servlet-name>action</servlet-name>
10. <servlet-class>
11. org.apache.struts.action.ActionServlet
12. </servlet-class>
13. <init-param>
14. <param-name>application</param-name>
15. <param-value>ApplicationResources</param-value>
16. </init-param>
17. <init-param>
18. <param-name>config</param-name>
19. <param-value>/WEB-INF/struts-config.xml</param-value>
20. </init-param>
21.</servlet> 88 DatTT-DSE-SOICT-HUST
Ví dụ: web.xml
1. <!-- Standard Action Servlet Mapping -->
2. <servlet-mapping>
3. <servlet-name>action</servlet-name>
4. <url-pattern>*.do</url-pattern>
5. </servlet-mapping>
6.
7. <!-- Struts Tag Library Descriptors -->
8. <taglib>
9. <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
10. <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
11. </taglib>
12. <taglib>
13. <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
14. <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
15. </taglib>
16. <taglib>
17. <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
18. <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
19. </taglib>
20.</web-app>
89 DatTT-DSE-SOICT-HUST
4. Internationalization
90 DatTT-DSE-SOICT-HUST
9/10/2011
16
Internationalization
 Mở rộng của java.util.ResourceBundle
 org.apache.struts.util.MessageResources
 Chỉ giới hạn hỗ trợ hiển thị. Nhập liệu tùy
theo thiết bị client
 Cấu hình resource bundles trong web.xml file
91 DatTT-DSE-SOICT-HUST
Internationalization: Nhiệm vụ của LTV
 Tạo resource file cho ngôn ngữ mặc định
 Tạo các resource files cho mỗi ngôn ngữ
muốn hỗ trợ
 Định nghĩa tên của các resource như các
tham số khởi tạo
 Trong trang JSP
 Sử dụng <html:errors/> để hiển thị các thông
báo lỗi theo locale
92 DatTT-DSE-SOICT-HUST
Resource files
 MyApplication.properties
 Chứa thông điệp viết bằng ngôn ngữ mặc định
 Mỗi thông điệp có dạng (vd Tiếng Anh):
 prompt.hello=Hello
 MyApplication_xx.properties
 Chứa cùng thông điệp tương đương, nhưng ở
các ngôn ngữ khác, có mã ngôn ngữ theo chuẩn
ISO là "xx"
 prompt.hello=Bonjour
93 DatTT-DSE-SOICT-HUST
Ví dụ: ApplicationResource.properties
1.errors.header=<h4>Validation Error(s)</h4><ul>
2.errors.footer=</ul><hr>
3.error.lastName=<li>Enter your last name
4.error.address=<li>Enter your address
5.error.sex=<li>Enter your sex
6.error.age=<li>Enter your age
94 DatTT-DSE-SOICT-HUST
Ví dụ: web.xml
1. <servlet>
2. <servlet-name>action</servlet-name>
3. <servlet-class>
4. org.apache.struts.action.ActionServlet
5. </servlet-class>
6. <init-param>
7. <param-name>application</param-name>
8. <param-value>
9. com.mycompany.mypackage.MyApplication
10. </param-value>
11. </init-param>
12. <!-- ... -->
13.</servlet>
95 DatTT-DSE-SOICT-HUST
5. (Input) Validation
96 DatTT-DSE-SOICT-HUST
9/10/2011
17
Validation: Nhiệm vụ của LTV (Struts 1.0)
 Chỉ định sẽ thực hiện validate input bằng thuộc tính
validate của phần tử <action> (con của phần tử
<action-mapping>) trong file servlet-config.xml
 validate=”true”
 Chỉ định trang JSP cần được hiển thị khi validation
không thành công
 input=”/errorpage.jsp”
 Override phương thức validate() trong lớp
ActionForm
 Tùy chọn
97 DatTT-DSE-SOICT-HUST
validate() method
 Được gọi bởi controller servlet
 Sau khi đã lấy xong các thuộc tính của bean
 Nhưng trước khi phương thức execute() của lớp Action
tương ứng được gọi
 Tùy chọn
 Phương thức mặc định trả về null
 Cú pháp:
 public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request);
98 DatTT-DSE-SOICT-HUST
Ví dụ: phương thức validate()
 Trong ứng dụng Login
 Cần đảm bảo nhập đồng thời cả “username” và
“password”
 Cần đảm bảo “password” có ít nhất là 6 ký tự
99 DatTT-DSE-SOICT-HUST
Phương thức validate()
 Sau khi thực hiện validate
 Nếu không xảy ra lỗi validate nào, trả về null
 Nếu xảy ra lỗi validate, trả về 1 thực thể của lớp
ActionErrors
 Mỗi ActionError chứa khóa thông điệp lỗi (error message key)
trong MessageResources bundle của ứng dụng
 Controller servlet lưu trữ mảng ActionErrors như 1 thuộc tính
request để sử dụng cho các thẻ <html:errors>
 Controller sau đó forwards điều khiển tở lại input form (xác định
trong thuộc tính input ho Actionmapping tương ứng)
100 DatTT-DSE-SOICT-HUST
Lớp ActionError
 Là cơ chế được sử dụng để trả về các lỗi khi
thực hiện validate input
 Đóng gói lại các lỗi
 Các message key được sử dụng để tìm kiếm ra
message text phù hợp từ các resource file
 ActionErrors là một tập các ActionError
101 DatTT-DSE-SOICT-HUST
struts-config.xml: Validation
1. <!-- ========== Action Mapping Definitions ============ -->
2. <action-mappings>
3. <action path="/submit"
4. type="hansen.playground.SubmitAction"
5. name="submitForm"
6. input="/submit.jsp"
7. scope="request"
8. validate="true">
9. <forward name="success" path="/submit.jsp"/>
10. <forward name="failure" path="/submit.jsp"/>
11. </action>
12. </action-mappings>
13.</struts-config>
102 DatTT-DSE-SOICT-HUST
9/10/2011
18
ActionForm
1.public final class SubmitForm extends ActionForm {
2.
3....
4. public ActionErrors validate(ActionMapping mapping,
5. HttpServletRequest request) {
6. ...
7.
8. // Check for mandatory data
9. ActionErrors errors = new ActionErrors();
10. if (lastName == null || lastName.equals("")) {
11. errors.add("Last Name", new ActionError("error.lastName"));
12. }
13. if (address == null || address.equals("")) {
14. errors.add("Address", new ActionError("error.address"));
15. }
16. if (sex == null || sex.equals("")) {
17. errors.add("Sex", new ActionError("error.sex"));
18. }
19. if (age == null || age.equals("")) {
20. errors.add("Age", new ActionError("error.age"));
21. }
22. return errors;
23. }
24...
25.}
103 DatTT-DSE-SOICT-HUST
Ví dụ: submit.jsp
1.<%@ page language="java" %>
2.<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
3.<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
4.<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
5.<html>
6.<head><title>Submit example</title></head>
7.<body>
8.<h3>Example Submit Page</h3>
9.<html:errors/>
10.<html:form action="submit.do">
11.Last Name: <html:text property="lastName"/><br>
12.Address: <html:textarea property="address"/><br>
13.Sex: <html:radio property="sex" value="M"/>Male
14. <html:radio property="sex" value="F"/>Female<br>
15.Married: <html:checkbox property="married"/><br>
16.Age: <html:select property="age">
17. <html:option value="a">0-19</html:option>
18. <html:option value="b">20-49</html:option>
19. <html:option value="c">50-</html:option>
20. </html:select><br>
21. <html:submit/>
22.</html:form>
104 DatTT-DSE-SOICT-HUST
Validator Framework trong Struts 1.1
 Validation logic có thể được mô tả trong file
cấu hình struts-config.xml
 Thay vì phải viết code phương thức Java:
validate()
(Struts nâng cao)
105 DatTT-DSE-SOICT-HUST
6. Xử lý lỗi (Error Handling)
106 DatTT-DSE-SOICT-HUST
CustomExceptionHandler (1.1)
 Tự định nghĩa lớp ExceptionHandler, được
gọi đến khi phương thức execute() của 1
Action ném ra 1 Exception
 Là lớp con của
org.apache.struts.action.ExceptionHandler
 Phương thức execute() phải xử lý Exception và
trả về 1 đối tượng ActionForward để thông báo
với Struts sẽ forward đến đâu tiếp
107 DatTT-DSE-SOICT-HUST
ExceptionHandler tự định nghĩa (1.1)
 Cấu hình bộ xử lý ngoại lệ trong struts-
config.xml
<global-exceptions>
<exception
key="some.key"
type="java.io.IOException"
handler="com.yourcorp.ExceptionHandler"/>
</global-exceptions>
 com.yourcorp.ExceptionHandler.execute() sẽ
được gọi khi có bất kỳ một IOException nào
được ném ra bởi một Action
108 DatTT-DSE-SOICT-HUST
9/10/2011
19
CustomExceptionHandler (1.1)
 Có thể có tác dụng global hoặc cho từng
action
<action ...>
<exception
key="some.key"
type="java.io.IOException"
handler="com.yourcorp.ExceptionHandler"/>
</action>
109 DatTT-DSE-SOICT-HUST
Ví dụ: ném ra một Exception
1.package hansen.playground;
2.import javax.servlet.http.*;
3.import org.apache.struts.action.*;
4.public final class SubmitAction extends Action {
5. public ActionForward execute(ActionMapping mapping,
6. ActionForm form,
7. HttpServletRequest request,
8. HttpServletResponse response) {
9. SubmitForm f = (SubmitForm) form; // get the form bean
10. // and take the last name value
11. String lastName = f.getLastName();
12. if (lastName.startsWith(“Passion”)){
13. // Translate the name to upper case
14. //and save it in the request object
15. request.setAttribute("lastName", lastName.toUpperCase());
16. // Forward control to the specified success target
17. return (mapping.findForward("success"));
18. }
19. else{
20. throw new WrongLastNameExcetion(lastName);
21. }
22. }
23.}
110 DatTT-DSE-SOICT-HUST
ExceptionHandler tự định nghĩa (1.1)
 Các ExceptionHandler khác nhau cho các lỗi
khác nhau
<global-exceptions>
<exception handler=
"com.cavaness.storefront.CustomizedExceptionHandler"
key="global.error.message"
path="/error.jsp"
scope="request"
type="java.lang.Exception"/>
<exception handler=
"com.cavaness.storefront.SecurityExceptionHandler"
key="security.error.message"
path="/login.jsp"
scope="request"
type="com.cavaness.storefront.SecurityException"/>
</global-exceptions>
111 DatTT-DSE-SOICT-HUST
7. View Selection
112 DatTT-DSE-SOICT-HUST
View Selection: Nhiệm vụ của LTV
 Trong file struts-config ,
 Với mỗi outcome (giá trị của thuộc tính name của
thẻ <forward>), chỉ định “trang JSP sẽ được
forward tới” nhờ thẻ con <forward>, con của thẻ
<action> hoặc thẻ <global-forwards>
 Trong phương thức execute() của lớp Action,
 Trả về đối tượng ActionForward, ứng với
outcome nào.
113 DatTT-DSE-SOICT-HUST
struts-config.xml: ActionMapping
1. <!-- ========== Action Mapping Definitions ============ -->
2. <action-mappings>
3. <action path="/submit"
4. type="hansen.playground.SubmitAction"
5. name="submitForm"
6. input="/submit.jsp"
7. scope="request"
8. validate="true">
9. <forward name="success" path="/submit.jsp"/>
10. <forward name="failure" path="/submit.jsp"/>
11. </action>
12. </action-mappings>
13.</struts-config>
114 DatTT-DSE-SOICT-HUST
9/10/2011
20
Ví dụ: Action Class
1.package hansen.playground;
2.import javax.servlet.http.*;
3.import org.apache.struts.action.*;
4.public final class SubmitAction extends Action {
5. public ActionForward execute(ActionMapping mapping,
6. ActionForm form,
7. HttpServletRequest request,
8. HttpServletResponse response) {
9. SubmitForm f = (SubmitForm) form; // get the form bean
10. // and take the last name value
11. String lastName = f.getLastName();
12. // Translate the name to upper case
13. //and save it in the request object
14. request.setAttribute("lastName", lastName.toUpperCase());
15.
16. // Forward control to the specified success target
17. return (mapping.findForward("success"));
18. }
19.}
115 DatTT-DSE-SOICT-HUST