109
J2EE 前前前前前前前前前 Struts Framework 廖廖廖 NCCU Computer Center Feb 2,2003

Struts Mitac(1)

Embed Size (px)

Citation preview

Page 1: Struts Mitac(1)

J2EE 前端應用程式架構與Struts Framework

廖峻鋒NCCU Computer Center

Feb 2,2003

Page 2: Struts Mitac(1)

Agenda Struts 簡介與定位 Web-tier 概觀 Framework & Design Patterns 概論

基本觀念與常用 OO 技巧簡介 Struts Framework Architectural Overview

The MVC Architectural Pattern Struts 設計理念

Struts 實作議題

Page 3: Struts Mitac(1)

What is Struts?

基於 MVC Architectural Pattern 所開發的 Web Application Framework

Craig McClanahan 在 2000 年提出, 2001 年 6月 release struts 1.0 。

Hosted in Apache Jakarta project 將開發 web 程式之 best practice 以 Application Fr

amework 的方式封裝,供開發人員重用。

為何有資格稱為 best practice ?

Page 4: Struts Mitac(1)

Must Read when Architecting J2EE Applications

P of EAACore J2EE Patterns 2/e

Page 5: Struts Mitac(1)

Struts 與 J2EE Core Patterns Struts 實作了下列 J2EE Core Patterns

Application Controller (PEAA) Front Controller (PEAA) View Helper (PEAA:Template View) Service to Worker Dispatcher View

Page 6: Struts Mitac(1)

Struts Framework 的定位

Web tier / Persistence /workflow

Your Code

WebLogic / WebSphere ?

jRocket VM / JDK ?

Linux / Windows ?

Struts is one of your architectural decisions

Page 7: Struts Mitac(1)

How Struts fits into RUP ?

Architecture should be finished

Page 8: Struts Mitac(1)

J2EE 前端的任務

UI ( 顯示畫面 ) Presentation Logic ( 顯示邏輯 ) Collects Inputs Page Flow Control

決定接下來要顯示那個 Page

當不使用 EJB 時… May Maintain State (HttpSession) May Implement Business Logic

J2EE 前端 = Web Tier

Page 9: Struts Mitac(1)

J2EE 前端的相關規格 / 技術 JSP / Servlets

最新版為 2.0 / 2.4 , 目前廣泛使用 1.2/2.3

JSP Custom Tag Library JSTL (JSP Standard Tag Library)

目前為 1.0 (2003.6)

JavaServer™ Faces 目前為 1.0 final draft (2003.12.19) UI components / UI Event Handling

Page 10: Struts Mitac(1)

問題與討論 試以簡圖表示 JSP 與 Servlet 如何運作 ? 什麼是 Container? 什麼是 Servlet Container? 至少說出三個 JSP 與 ASP 不同之處 ? 一個完全使用 Servlet 的應用程式可能有什麼缺點 ? 什麼是 scriptlet ? 一個完全使用 scriptlet 的 JSP 應用程

式可能有什麼缺點 ? JSP 1.2 規格書中訂有那四個 scope ,其意義為何 ? 使

用時機為何 ? 請舉例說明一個合乎 Servlet 2.3 規格書的 Web Applicati

on 應該長什麼樣子。 Forward 和 Redirect 有何不同 ?

Page 11: Struts Mitac(1)

Framework and Design Patterns

Struts Framework is built upon several well-known proven patterns

簡介

Page 12: Struts Mitac(1)

如果建築師都用軟體工程師的方法來建造房子,那麼第一隻飛來的啄木鳥便足以將整個文明都給摧毀。- Applied Java Patterns by Stephen Stelting and Olava Maassen

Page 13: Struts Mitac(1)

Design Patterns Christopher Alexander (U.C. Berkeley) – 1977 出版了一

本建築學用的樣式目錄 (Pattern- Catalog) 。 1987 OOPSLA 中 Kent Beck 等人發表了 smalltalk 的 D

esign Patterns 。 1995 年 Gof 出版了 Design patterns:Elements of Reus

able Object-Oriented Software 。 1996 年 Frank 等人出版了 POSA(Pattern Oriented Soft

ware Architecture) 。 這二本書問世後, Design Patterns 開始受到廣泛的重視

與成長。

Page 14: Struts Mitac(1)

Two primary books POSA Gof

Page 15: Struts Mitac(1)

Pattern System 由 [POSA96] 首先提出對 Patterns 的分類 將 Pattern 從「鉅觀」到「微觀」加以分類

Architectural Patterns ( 例如 :MVC 、 Layer) Design Patterns ( 例如 :Gof 的 23 個 patterns) Idioms ( 例如大量接合字串問題或 Code Style)

Page 16: Struts Mitac(1)

框架 (Framework) A framework is a reusable, semi-complete appli

cation( 半成品 ) that can be specialized to produce custom applications.

Application frameworks are for reifying( 具體化 ) proven software designs and implementations.

Framework 通常針對特定領域來設計。

讓成功的設計經驗可以重複使用 !

Page 17: Struts Mitac(1)

框架與應用程式的關係 框架可以看成是整個應用程式的骨架,程式開發人員將框架客製化以寫出真正的應用程式。

框架( 抽象的、不能使

用 )

應用程式( 具體的、可

以使用的 )

客製化

Page 18: Struts Mitac(1)

Framework 與 Patterns 的比較 Design Patterns 是從很多 Framework 中歸納得來。

一個 Framework 可能會包括很多 Design Patterns 。

Design Patterns 只能在觀念層級被重用。 Patterns are more abstract than frameworks

Framework 通常會由一群 Design Patterns 組成。

Page 19: Struts Mitac(1)

使用 Framework 的好處 ? 讓成功的經驗得以重複使用。 將領域專家 (Domain Expert) 的知識封裝於 Fram

ework 中。 鼓勵重用。 增進開發效率。 將軟體開發經驗轉換成具體資產。

Page 20: Struts Mitac(1)

Applying Framework Framework Develop time

2002.11 ~ 2003.06 (7 個月 / 1 人 )

Applications Develop time 改寫時間 2003.7 ~ 2003.8 (2 個月 / 2 人 )

Page 21: Struts Mitac(1)

使用 Framework 的經驗 Developers should have strong OO background

s. 在 Programmer 沒有足夠 OO Background 的情況下套用 Framework 可能造成反效果 .

Learning curve should be taken into account. Once framework is on-line , it will be very hard t

o modified.

Page 22: Struts Mitac(1)

Framework and Design Patterns

幾個常用到的基本技巧

Page 23: Struts Mitac(1)

實作和流程控制角色互換 (Inversion of Control)

傳統的公用函式庫 (Library) 函式由函式庫定義。 我們寫主程式,在主程式中呼叫函式。 你控制流程, Library 提供實作。

框架 (Framework) 主程式由框架定義。 我們實作函式,被框架定義的主程式所呼叫。 Framework 控制流程,它會呼叫你所提供的實作 !

又稱 :HollyWood 法則 Don’t call me, I will call you!

Page 24: Struts Mitac(1)

Inversion of ControlLibrary 使用者的實作 Framework 使用者的實作

Page 25: Struts Mitac(1)

Library Reuse

String countStr = “256”;

String count = Integer.parseInt(countStr);

你控制流程, Library 提供實作 !

Structured Style!

Page 26: Struts Mitac(1)

Framework Reuse

public class MyServlet extends HttpServlet

{

public void doGet(…){

// 提供實作 }

}

Framework 控制流程,你提供實作 !

Call Back Style!

Page 27: Struts Mitac(1)

建構框架基本原則-Essential Framework construction principles

Unification Separation

Page 28: Struts Mitac(1)

Template Method /Hook Method

Framework 的作者通常將主要邏輯寫在 Template Method 中。

Template Method 會呼叫若干 Hook Method , Hook Method 通常就是「變異點 (Hot Spot) 」。

覆寫 Hook Method ,就可改變 Template Method的行為。 ( 例如 Servlet 的 doGet()/doPost() )

參考下頁的例子。

Page 29: Struts Mitac(1)

範例 :LoginHandler

Page 30: Struts Mitac(1)

Unification

Template method

Hook method

template 、 hook 在同一個 Class

Page 31: Struts Mitac(1)

Servlet 與Template Method [Gof95] 一個 Browser向 HttpServlet 發出 post 時,會觸發 doPost() 方法。

一個 Browser向 Servlet 發出 get 時,會觸發 doGet() 方法。

判別是 get 或 post ,由 HttpServlet 決定,至於 doPost() , doGet() 由子類別決定。

Template Method 是 Framework 中最常見到的Design Pattern!

Page 32: Struts Mitac(1)

Servlet

Page 33: Struts Mitac(1)

Interface Interface 規定了一組契約 (method) ,所有實作它的類別都要實作所有方法。

Client 呼叫的是 Interface 中的方法,所以元件的抽換對 Client 來說是感覺不到的 ( 不用改 code) 。

Page 34: Struts Mitac(1)

實作界面就可保証符合規格

Page 35: Struts Mitac(1)

java.io.FilenameFilterps. 其實這是一個 strategy pattern

Page 36: Struts Mitac(1)

Separation

Template method

Hook method

Template Class 與 Hook Class 有委任關係

Observer Pattern

Page 37: Struts Mitac(1)

範例 : 時常需要切換多台資料庫template method hook method

在 template method 中呼叫 hook method

Page 38: Struts Mitac(1)

討論 : 彈性的登入機制Which is template method ? which is hook method ?

Page 39: Struts Mitac(1)

Struts Architectural Overview

Page 40: Struts Mitac(1)

伺服端應用程式設計的演進 Servlet JSP scriptlet JSP+Bean (Model 1, Page Controller) MVC (Model 2)

Page 41: Struts Mitac(1)

Model 1

在 JSP 中決定下一頁是那裏,所以稱為 Page Controller ,通常 Page Controller 會有多個。 (PEAA)

ASP.NET 的標準做法

Page 42: Struts Mitac(1)

Model 1 : Page Controller

login.jsp 資料庫index.htm

index.jsp

在 JSP 中決定下一頁是那裏,所以稱為 Page Controller

Java Bean

Request or Session Scope

Page 43: Struts Mitac(1)

Model 1 有什麼問題 ?

Servlet/JSP

Servlet/JSP

Servlet/JSP

Web Server

Servlet/JSP

One controller per page , hard to maintain !

Page 44: Struts Mitac(1)

MVC : Separation of Concern

C

V

M

Page 45: Struts Mitac(1)

Model 2 - MVC

index.jsp

BOindex.htm ControllerServlet

Java Beanread data

set data

Request or Session Scope

Forward/Redirect

Page 46: Struts Mitac(1)

Controller Split

index.jspLoginAction BO

Request or Session Scope

index.htm

Java Bean

Controller

Page 47: Struts Mitac(1)

Controller Split in Struts

Controller = ActionServlet + Action Classes

Page 48: Struts Mitac(1)

MVC

index.jspLoginAction BO

Request or Session Scope

index.htm

Java Bean Model

View Controller

Controller

Page 49: Struts Mitac(1)

Struts 的 MVC 模型

index.jspAction Class Business

Logic

Request or Session Scope

index.htm

ActionForm Model

View Controller

ActionServlet

Page 50: Struts Mitac(1)

Strengths of MVC Pattern Provides a clear separation between:

Business Logic (M) Output Presentation (V) Request Processing (C)

Provides single point of workflow control

Increases code manageability Increases code extensibility

Page 51: Struts Mitac(1)

MVC Implementations Hans MVC Struts Framework

Page 52: Struts Mitac(1)

MVC 實作基本觀念 (1)

index.do

Action String Controller String

Controller String 用來指定 Controller 類別來處理Action String 用來指定要交給那個 Action 類別處理

http://localhost:8080/jpetstore/index.do

Page 53: Struts Mitac(1)

MVC 實作基本觀念 (2) Action Table 在 Controller 中以 HashMap 方式實作

Controller 經由查表可得知該使用那個那個 Action 類別來處理該 Action String 。Action String Action 類別

index IndexAction

viewCategory ViewCategoryAction

Page 54: Struts Mitac(1)

Hans MVC

Page 55: Struts Mitac(1)

簡單的 MVC 實作

查表

Page 56: Struts Mitac(1)

Struts modifications

struts-config.xml

ActionServlet+

RequestProcessor

Abstract Action

Page 57: Struts Mitac(1)
Page 58: Struts Mitac(1)

使用 ActionForm來協助處理 HTML 表單

每一個 HTML Form背後都有一個 ActionForm來 support 。

id

password

<<ActionForm>>

LoginActionForm

idpasswordgetId()/setId()getPassword()setPassword()reset()validate()

Page 59: Struts Mitac(1)

ActionForm 的處理

askName.jsp

ProcessNameAction

ActionServlet/processName.do

UserNameForm

ActionSerlvet 會依據 config 檔將使用者填入的資料填入 ActionForm 中

ActionForm 的會以參數的形式傳給 Action 類別,供開發者在取得 ActionForm 的資料

<<ActionForm>>

<<Action>>

Page 60: Struts Mitac(1)

struuts-config.xml 主要區段 依先後次序為 :

1. DataSource 設定 (JDBC)

2. ActionForm 設定 重要 !

3. Global相關設定4. ActionMapping 設定 重要 !

5. Controller 設定6. 其它設定 (i18n,plug-in,resource…)

Page 61: Struts Mitac(1)

struts-config.xml

ActionForm 設定

ActionMapping 設定

Page 62: Struts Mitac(1)

struts-config.xml 的處理

Page 63: Struts Mitac(1)

Author: Jean-Michel Garnier , http://rollerjm.free.fr/pro/Struts11.html

Page 64: Struts Mitac(1)

Developing Web Applications with Struts Framework

Page 65: Struts Mitac(1)

Struts 主要元件 Struts JSP自訂標籤庫 ActionForm Action classes ActionServlet

struts-config.xml

Page 66: Struts Mitac(1)

Struts - View

Page 67: Struts Mitac(1)

JSP 的寫作 : 二種選擇 JSTL

<c:out value=“${sessionScope.userBean.name}” />

Struts-bean <bean:write name=“userBean” property=“name” />

Page 68: Struts Mitac(1)

JSTL 與 Struts Tag ,何者優先 ?

Should you use JSTL tags instead of Struts tags whenever you can? Sure, if your container supports Servlets 2.3 and JSP 1.2, and that’s what you want to do.( 儘可能使用JSTL 取代 Struts 標籤 )

If JSTL already existed, most of the Struts tags would neverhave been written.

-Ted Husted ,Jakarta Struts technical lead.

JSTL 優先 !

Page 69: Struts Mitac(1)

JSTL 與 Struts tag 取捨準則 (摘自 Struts in Action by Ted Husted)

使用 JSTL取代 <bean:…> 與 <logic:…>繼續使用 <html:……>

目前 Struts 正在開發 Struts-EL ,未來在 <html:…> 中將可使用 Expression Language.

Page 70: Struts Mitac(1)

使用 Struts 控制項取代傳統 Html 控制項

目的 : 使用 Struts 的 html 控制項才能利用 ActionForm 的好處。

有時會和 JSTL 一起合併使用。

Page 71: Struts Mitac(1)

傳統的 Html Form

<html>

<body>

<form action=“sayHello.do”>

<input type=“text” name=“userName”/>

<input type=“submit” />

</form>

</body>

</html>

Page 72: Struts Mitac(1)

使用 Struts 控制項取代 html 控制項 修改 web.xml 副檔名改成 .jsp 修改 tag

Page 73: Struts Mitac(1)

修改 web.xml

<taglib>

<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>

<taglib-location>

/WEB-INF/tld/struts-html.tld

</taglib-location>

</taglib>

使用 Struts 控制項取代傳統 html 控制項

隨便取個名字,識別用 .

TLD 真正的位置

Page 74: Struts Mitac(1)

使用 Struts 控制項取代傳統 html 控制項

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html:html>

<html:form action=“sayHello.do”>

<html:text property=“userName” />

<html:submit />

</html:form>

</html:html>

要先宣告

前面加上 html 的 prefix

相同 !

Page 75: Struts Mitac(1)

HTML 的 Form 如何與 ActionForm 對映 ? 基本上每一個 <html:form>……</html:form>背後都會有一個 ActionForm 。

表單的每一個輸入欄位原則上對映到 JavaBean的一個 property 。

Page 76: Struts Mitac(1)

範例<html:html>

<html:form action=“sayHello.do”>

<html:text name=“userNameForm” property=“userName” />

<html:text name=“userNameForm” property=“password” />

<html:submit />

</html:form>

</html:html> ActionForm 名稱

所對映到的屬性

Page 77: Struts Mitac(1)

UserNameFormPackage demo;Public class UserNameForm extends ActionForm{ // 屬性和 html form 的要一一對應,名字也要相同 private String userName; private String password; // 每一個屬性都要有 getter及 setter public void setUserName(String userName) {…} public String getUserName() {…..} public void setPassword(){…..} public String getPassword() {….}}

如果欄位很多,寫起來很麻煩 ?

Page 78: Struts Mitac(1)

在那裏登記 ActionForm?

ActionForm 設定

Page 79: Struts Mitac(1)

登記 ActionForm

<form-bean

name=“userNameForm”

type=“demo.UserNameForm”

/>

其它屬性className – 指定 FormBeanConfig 類別。dynamic – 是否使用 DynaForm ?

ActionForm 類別名稱

ActionForm 的名字,將在ActionMapping 區段中使用

Page 80: Struts Mitac(1)

使用 DynaBean

<form-bean

name=“userNameForm”

type=“org.apache.struts.action.DynaActionForm”

dynamic=“true” >

<form-property name=“userName” type=“java.lang.String”/>

<form-property name=“password” type=“java.lang.String”/>

</form-bean>

使用單一 Map 物件儲存所有 JavaBean 的屬性

登記屬性名稱

Page 81: Struts Mitac(1)

public class ProcessNameAction extends Action{ public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { UserNameForm myForm = (UserNameForm) form; …..(do something)… return (mapping.findForward(“sayHello")); }}

讀取 ActionForm 的資料

以參數形式傳入

取得 ActionForm 的參考

Page 82: Struts Mitac(1)

Action Class

Page 83: Struts Mitac(1)

(revisited) Struts 的 MVC 模型

index.jspAction Class Business

Logic

Request or Session Scope

index.htm

ActionForm Model

View Controller

ActionServlet

Page 84: Struts Mitac(1)

Action 做些什麼 ?

1. 從 ActionForm 中取得資料2. 從 request/response 中取得資料3. 委任商業邏輯 (含資料庫存取 )

4. 將控制權 forward 到合適的 View 中

Page 85: Struts Mitac(1)

ProcessNameActionpublic class ProcessNameAction extends Action{ public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { UserNameForm myForm = (UserNameForm) form; …..(do something)… return (mapping.findForward(sayHello")); }}

Page 86: Struts Mitac(1)

ActionServlet 使用 struts-config.xml 控制ActionServlet 行為 !

Page 87: Struts Mitac(1)

Struts-config.xml Struts 的核心,用來描述各元件的關係。 市面上有很多 GUI 工具可支援自動產生。

Page 88: Struts Mitac(1)

struuts-config.xml 主要區段 依先後次序為 :

1. DataSource 設定 (JDBC)

2. ActionForm 設定 重要 !

3. Global相關設定4. ActionMapping 設定 重要 !

5. Controller 設定6. 其它設定 (i18n,plug-in,…)

我們只講 ActionForm及 ActionMapping ,其它config 的細節請自行參考 struts線上文件。

Page 89: Struts Mitac(1)

ActionForm 區段 目的 : 在此宣告你寫的 ActionForm及其代名 ( 你要怎麼稱呼他 ?) ,以便在 ActionMapping 中做相對設定。

以 <form-beans>…</form-beans> 為界。 <form-beans> 中包含數個 <form-bean> 。

Page 90: Struts Mitac(1)

ActionForm 區段<form-beans> <form-bean name="userNameForm" type="simple.form.SimpleForm“ /> <form-bean name=“anotherForm" type="simple.form.AnotherForm“ /></form-beans>

ActionMapping 區段將使用這個名字來指稱你的 FormBeans

Page 91: Struts Mitac(1)

ActionMappings 區段 目的 : 將 jsp背後的 ActionForm 、發出的 url 、

Action class及其處理完後要 forward 的對象,四者間的關係連結起來。

Page 92: Struts Mitac(1)

ActionMappings 區段 如何將以下這幾個 component 的關係化成文字 ?

index.jsp

SayHelloActionhello.jsp

ActionServlet/sayHello.do

success

Request Scope

UserNameForm

Page 93: Struts Mitac(1)

ActionMappings 區段<action-mappings> <action path="/sayHello" type="simple.action.SayHelloAction" name="userNameForm" scope="request" input=“index.jsp” > <forward name="success" path="/hello.jsp"/> </action> <action>…..</action> <action>…..</action></action-mappings>

要將 .do 去掉

Page 94: Struts Mitac(1)

Struts Application Demo(1)- 使用 JBuilder X

Page 95: Struts Mitac(1)

系統設計

askName.jsp

ProcessNameActionsayHello.jsp

ActionServlet/processName.do

sayHello

Request Scope

UserNameForm

Page 96: Struts Mitac(1)

輸入驗証 (Validation) Client side validation Server side validation

實作 ActionForm.validate()

Page 97: Struts Mitac(1)

Struts 的輸入驗証架構

Page 98: Struts Mitac(1)

實作 validation 步驟1. 在 ActionForm 中實作 validate 方法2. struts-config.xml 中的 <action>標籤中之 valida

te屬性設為 true

3. 設定 ApplicationResource.properties

4. 寫作 ActionError 與錯誤訊息

Page 99: Struts Mitac(1)

Struts Application Demo(2)-validation

Page 100: Struts Mitac(1)

Struts 就這樣嗎 ? 還有很多有趣的細節等待你發掘。 Tiles – Template framework 更多 Default Action Classes ProcessBean Validating Framework Exception Handling I18n

建議參考書藉 – Struts in Action by T.Husted et al.

Page 101: Struts Mitac(1)

其它注意事項

Page 102: Struts Mitac(1)

Q & A [email protected] http://java.cc.nccu.edu.tw

Page 103: Struts Mitac(1)

backup

Page 104: Struts Mitac(1)

Request Dispatching /sales/report?month=Jan

Servlet Context

Context Path

Query String

Page 105: Struts Mitac(1)

Framework 進階閱讀 Building Application Framework (Wiley)- 這本很像論文集,不好唸且錯誤很多,宜以讀書會方式加以了解。

Java Application Framework (Wiley). 應用架構入門與實例 – 台灣本土唯一一本 Fram

ework 著作,但是是數年前的著作,前幾章仍有閱讀的價值。 ( 可自MISOO上自由下傳 ) 。

Page 106: Struts Mitac(1)

Design Patterns 學習地圖 精通任一種 OO語言及 OO 基本觀念 (繼承封裝多形 ) 。 Thinking in Java( 有中譯本 ) .

Design Patterns入門 Java 與樣式理論 / Java 與樣式實作 (閻宏 ) Applying UML and Patterns: An Introduction to Objec

t-Oriented Analysis, 2/e( 有中譯本 ) Design Patterns Explained: A New Perspective on O

bject-Oriented Design( 有中譯本 ) Design Patterns 於 Java 語言上的實習應用 ( 有中譯本 )

Page 107: Struts Mitac(1)

Design Patterns 學習地圖 2 觀察別人如何使用 Patterns(Java)

Java Design Patterns: A Tutorial Applied Java Patterns( 有中譯本 ) Patterns in Java VI,V2.

活用 Patterns Design Patterns Java Workbook( 有中譯本 ) Pattern Hatching: Design Patterns Applied( 這本是以

C++ 為例 ).

Page 108: Struts Mitac(1)

Design Patterns 學習地圖 3 經典

Gof( 有中譯本 )

Architectural Patterns Patterns of Enterprise Application Architecture Pattern Oriented Software Architecture (POSA)

• 這本書 scope非常廣,包含了 Software Architecture 、 Architectural Patterns 、 Design Patterns及 Idioms 。

Page 109: Struts Mitac(1)

Design Patterns 學習地圖 4 Enterprise Design Patterns

Patterns in Java V3 POSA2 Core J2EE Patterns / 2e P of EAA

HillSide Group(http://hillside.net) - 由 Kent Beck 及 Grady Booch 建立,是 Pattern族群的聖殿。