9/10/2011s3.amazonaws.com/zanran_storage/soict.hut.edu.vn/ContentPages/... · 9/10/2011 3 Struts:...
Transcript of 9/10/2011s3.amazonaws.com/zanran_storage/soict.hut.edu.vn/ContentPages/... · 9/10/2011 3 Struts:...
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: [email protected]/[email protected]
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
1DatTT-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ề2DatTT-DSE-SOICT-HUST
1.1. Struts là gì?
3DatTT-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/
4DatTT-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
5DatTT-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
6DatTT-DSE-SOICT-HUST
9/10/2011
2
1.2. Tại sao sử dụng Struts
7DatTT-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ở8DatTT-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)
9DatTT-DSE-SOICT-HUST
2. Kiến trúc của Struts
10DatTT-DSE-SOICT-HUST
Model-View-Control (model 2)
Request
1
(Controller)Servlet
(View)JSPResponse
5
3
4
BR
OW
SE
R
Servlet Container (EIS)
Redirect2
(Model)Java Bean
MVC Design Pattern
11DatTT-DSE-SOICT-HUST
Struts hoạt động như thế nào
12DatTT-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
13DatTT-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
14DatTT-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
15DatTT-DSE-SOICT-HUST
2.1. Controller
16DatTT-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
17DatTT-DSE-SOICT-HUST
Các thành phần Controller
18DatTT-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ể
19DatTT-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
20DatTT-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
21DatTT-DSE-SOICT-HUST
2.1.1. ActionServlet(Framework cung cấp)
22DatTT-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
23DatTT-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
24DatTT-DSE-SOICT-HUST
9/10/2011
5
Điều khiển luồng bởi Controller
25DatTT-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.
26DatTT-DSE-SOICT-HUST
2.1.2. RequestProcessor(Framework cung cấp)
27DatTT-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
28DatTT-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
29DatTT-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.
30DatTT-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
31DatTT-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.
32DatTT-DSE-SOICT-HUST
2.1.3. Action Mapping(LTV viết)
33DatTT-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
34DatTT-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
35DatTT-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
36DatTT-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 PUBLIC3. "-//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>
37DatTT-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>
38DatTT-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 39DatTT-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>
40DatTT-DSE-SOICT-HUST
struts-config.xml: <action-mappings>
1. <action-mappings>
2. <action3. 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>
41DatTT-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) 42DatTT-DSE-SOICT-HUST
9/10/2011
8
Global Forwarding
1.<struts-config>2. <form-beans>3. <form-bean4. name="logonForm"5. type="org.apache.struts.webapp.example.LogonForm" />6. </form-beans>7. <global-forwards8. type="org.apache.struts.action.ActionForward">9. <forward 10. name="logon" 11. path="/logon.jsp"12. redirect="false" />13. </global-forwards>14.
43DatTT-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>
44DatTT-DSE-SOICT-HUST
2.1.4. ActionForm(LTV phải cung cấp, nếu không sử dụng DynaActionForm)
45DatTT-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
46DatTT-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
47DatTT-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
48DatTT-DSE-SOICT-HUST
9/10/2011
9
Ví dụ:
subm
it.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>49DatTT-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 value7. 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.... 50DatTT-DSE-SOICT-HUST
struts-config.xml: <form-beans>
1.<?xml version="1.0" encoding="ISO-8859-1" ?>
2.<!DOCTYPE struts-config PUBLIC3. "-//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>
51DatTT-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>
52DatTT-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)
53DatTT-DSE-SOICT-HUST
2.1.5. Action(LTV tự viết)
54DatTT-DSE-SOICT-HUST
9/10/2011
10
Action Class Diagram
55DatTT-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 nó
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
56DatTT-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
57DatTT-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”
58DatTT-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)
59DatTT-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,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception;
60DatTT-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,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException;
61DatTT-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
62DatTT-DSE-SOICT-HUST
Ví dụ: lớp Action1.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.}63DatTT-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
64DatTT-DSE-SOICT-HUST
Ví dụ 2: Lớp Action1.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.}65DatTT-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>66DatTT-DSE-SOICT-HUST
9/10/2011
12
Các lớp Action xây dựng sẵn
ForwardAction
DispatchAction
(Advanced Struts)
67DatTT-DSE-SOICT-HUST
2.2. Các thành phần Model (Model Components)
(LTV viết)
68DatTT-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
...
69DatTT-DSE-SOICT-HUST
Model components
70DatTT-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
71DatTT-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"/>
72DatTT-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
73DatTT-DSE-SOICT-HUST
Struts Model Components
System State Bean & Business logic Bean
74DatTT-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
75DatTT-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
76DatTT-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
77DatTT-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
78DatTT-DSE-SOICT-HUST
9/10/2011
14
2.3. Các thành phần View (View Components)
LTV phải cung cấp
79DatTT-DSE-SOICT-HUST
View components
80DatTT-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
81DatTT-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
82DatTT-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"/>;
83DatTT-DSE-SOICT-HUST
Ví dụ: submit.jsp1.<%@ 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>
84DatTT-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>
85DatTT-DSE-SOICT-HUST
3. web.xml
86DatTT-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
87DatTT-DSE-SOICT-HUST
Ví dụ: web.xml
1.<!DOCTYPE web-app2. 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.ActionServlet12. </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> 88DatTT-DSE-SOICT-HUST
Ví dụ: web.xml1. <!-- 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>89DatTT-DSE-SOICT-HUST
4. Internationalization
90DatTT-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
91DatTT-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
92DatTT-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
93DatTT-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
94DatTT-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>
95DatTT-DSE-SOICT-HUST
5. (Input) Validation
96DatTT-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
97DatTT-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);
98DatTT-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ự
99DatTT-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)
100DatTT-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
101DatTT-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>102DatTT-DSE-SOICT-HUST
9/10/2011
18
ActionForm1.public final class SubmitForm extends ActionForm {2.3....4. public ActionErrors validate(ActionMapping mapping,5. HttpServletRequest request) {
6. ...7.8. // Check for mandatory data9. 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.}
103DatTT-DSE-SOICT-HUST
Ví dụ: submit.jsp1.<%@ 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> 104DatTT-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)
105DatTT-DSE-SOICT-HUST
6. Xử lý lỗi (Error Handling)
106DatTT-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
107DatTT-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
108DatTT-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>
109DatTT-DSE-SOICT-HUST
Ví dụ: ném ra một Exception1.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.}110DatTT-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> 111DatTT-DSE-SOICT-HUST
7. View Selection
112DatTT-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.
113DatTT-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>114DatTT-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.}115DatTT-DSE-SOICT-HUST