WebX框架解析及使用教程

原文連接:http://blog.sina.com.cn/s/blog_628cc2b70102v115.htmlcss

1、Webx的層次結構(從裏到外)html

(1)SpringExt:基於Spring,提供擴展組件的能力java

(2)Webx Framework:基於Servlet API,提供基礎服務web

(3)Webx Turbine:基於Webx Framework,實現具體的網頁功能數據庫

2、Webx的初始化緩存

位置:/WEB-INF/web.xml文件服務器

<!-- Loading /WEB-INF/webx.xml, /WEB-INF/webx-*.xml -->
	<listener>
		<listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class>
	</listener>

結果:自動搜索/WEB-INF目錄下的XML配置文件,並建立級聯的Spring容器。cookie

/WEB-INF/webx.xml->/WEB-INF/web-app1.xml->/WEB-INF/webx-app2.xmlsession

3、初始化日誌系統app

添加方式:

<!-- Logger -->
	<listener>
		<listener-class>com.alibaba.citrus.logconfig.LogConfiguratorListener</listener-class>
	</listener>

4、Webx響應請求

Webx響應請求的流程:

(1)WebxFrameworkFilter接收請求

(2)WebxRootController建立和處理request context,路由到子應用,並提供處理異常、開發模式功能。

(3)WebxController進行apps' pipeline

當一個HTTP請求到達時,WebxFrameworkFilter接收請求的模板配置(/WEB-INF/webx.xml)以下:

<filter>
		<filter-name>webx</filter-name>
		<filter-class>com.alibaba.citrus.webx.servlet.WebxFrameworkFilter</filter-class>
		<init-param>
			<!--排除URL,以逗號隔開-->
			<param-name>excludes</param-name>
			<param-value>*.css, *.js, *.jpg, *.gif, *.png, *.jpeg,/sendBucSSOToken,/bucSSOLogout</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>webx</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

爲何使用filter而不是servlet?若是webx發現某個請求不該該由webx來處理,就會把控制「返還」給原來的控制器,而Servlet不具有「返還控制」的機制。

RequestContext對象的標準模板以下:

<!-- 當接受到請求後,從新設置request/response/session。 -->
    <services:request-contexts xmlns="http://www.alibaba.com/schema/services/request-contexts">
        <rewrite>
        	<rule pattern=".*\.htm">
				<substitution uri="$0" flags="L,QSA" />
			</rule>
			<rule pattern=".*">
				<substitution flags="L,QSA" />
				<handlers>
                    <!--執行RestfuleUrlRewriter類設置request/response/session-->
					<rewrite-handlers:handler
						class="com.alibaba.dubbo.governance.web.common.interceptor.RestfuleUrlRewriter" />
				</handlers>
			</rule>
        </rewrite>
        <basic />
        <buffered />
        <lazy-commit />
        <parser />
        <!--設置request/response/session編碼-->
        <set-locale defaultLocale="zh_CN" defaultCharset="UTF-8" />
        <session>
            <id>
                <cookie path="/" maxAge="0" httpOnly="true" />
            </id>
            <stores>
                <session-stores:cookie-store id="temporaryCookie">
                    <session-stores:cookie name="tmp" />
                </session-stores:cookie-store>
            </stores>
            <store-mappings>
                <match name="*" store="temporaryCookie" />
            </store-mappings>
        </session>
    </services:request-contexts>

 

5、Webx Turbine

它的基本準則是:約定勝於配置,即:工程師只須要根據必定的規則,將模板放在指定的目錄、按照預約的方式命令module(也就是screen、action、control等),就再也不須要額外的配置。

Turbine的基本頁面組成爲:

(1)Screen:表明頁面的主體

(2)Layout:表明頁面的佈局

(3)Control:表明嵌在screen和layout中的頁面片斷

頁面佈局圖以下:

【重要】WebX框架解析及使用教程之一

6、Webx Turbine處理頁面的基本流程

Webx Turbine的處理流程被定義在pipeline中,pipeline推薦的配置以下:

<services:pipeline
		xmlns="http://www.alibaba.com/schema/services/pipeline/valves">
		<!-- 初始化turbine rundata,並在pipelineContext中設置可能會用到的對象(如rundata、utils),以便valve取得。 -->
		<prepareForTurbine />
		<!-- 設置日誌系統的上下文,支持把當前請求的詳情打印在日誌中。 -->
		<setLoggingContext />
		<!-- 分析URL,取得target。 -->
		<analyzeURL />
		<!-- 檢查csrf token,防止csrf攻擊和重複提交。假如request和session中的token不匹配,則出錯,或顯示expired頁面。 -->
		<checkCsrfToken />
		<!-- 攔擊器做用 -->
        <!-- 設置語言:顯示本地語言和風格的頁面 -->
		<valve class="com.alibaba.dubbo.governance.web.common.interceptor.LocaleValve" />
		<choose>
			<when>
				<pl-conditions:path-condition name="^/servicestatus/.+|^/status$|/favicon.ico|/sysinfo/dump.htm" />
			</when>
			<otherwise>
                <!-- 頁面受權:根據登陸用戶的權限,阻止或許可用戶訪問特定的頁面。-->
				<valve class="com.alibaba.dubbo.governance.web.common.interceptor.AuthorizationValve" />
			</otherwise>
		</choose>
		<loop>
			<choose>
				<when>
					<!-- 執行不帶模板的screen,默認無layout。 -->
					<pl-conditions:path-condition
						name="/sysinfo/dump.htm|^/\w+$|^/status/.+$" />
					<performTemplateScreen />
				</when>
				<when>
					<!-- 執行帶模板的screen,默認有layout。 -->
					<pl-conditions:target-extension-condition
						extension="null, vm, jsp, html" />
					<!--執行action-->
					<performAction />
					<!-- 執行screen-->
					<performTemplateScreen />
					<!--渲染模板-->
					<renderTemplate />
				</when>
				<otherwise>
					<!--把控制權還給servlet engine-->
					<exit />
				</otherwise>
			</choose>

			<!-- 假如rundata.setRedirectTarget()被設置,則循環,不然退出循環。 -->
			<breakUnlessTargetRedirected />
		</loop>
	</services:pipeline>

 

流程具體解讀以下:

(1) 分析URL::用戶訪問的主頁target

(2) 進入choose,進行多重分支選擇

(3)performAction執行action

(4) performTemplateScreen查找並執行screen

假設target爲xxx/yyy/zzz,那麼Webx Turbine查找screen模塊的順序爲:

Screen.xxx.yyy.zzz

Screen.xxx.yyy.Default

Screen.xxx.Default

Screen.Default

(5) 渲染模板

首先映射成screen template,以及映射成layout template

假設target爲xxx/yyy/zzz,那麼Webx Turbine會查找下面的screen模板:/templates/screen/xxx/yyy/zzz。Screen模板若是未找到,就會報404 Not Found錯誤。 找到screen模板之後,Webx Turbine還會試着查找下面的layout模板:

/templates/layout/xxx/yyy/zzz

/templates/layout/xxx/yyy/default

/templates/layout/xxx/default

/templates/layout/default

Layout模板若是找不到,就直接渲染screen模板;若是存在,則把渲染screen模板後的結果嵌入到layout模板中。

7、Filter的用途

頁面受權:根據登陸用戶的權限,阻止或許可用戶訪問特定的頁面。

日誌和審計:記錄和檢查用戶訪問WEB應用的狀況。

圖片轉換:改變圖片的格式、精度、尺寸等。

頁面壓縮:壓縮頁面內容,加快下載速度。

本地化:顯示本地語言和風格的頁面。

XSLT轉換:對XML內容進行XSLT轉換,使之適用於多種客戶端。

高速緩存:高速緩存頁面,提升響應速度。

使用方法:【重要】WebX框架解析及使用教程之一

Webx提供了Request Contexts服務以及Pipeline做爲對Filter功能缺陷的補充,做用分別以下:

(1) Request Contexts:負責訪問和修改request和response,但不負責改變應用執行的流程

(2) Pipeline:提供應用執行的流程,但不關心和request和response

8、Spring中依賴注入的限制

小做用域的對象不能被注入到大做用域的對象。你不能把request和response做用域的對象注入到singleton對象中。前者在每次WEB請求時,均會建立新的實例,每一個線程獨享這個request/session做用域的對象;後者是在Spring初始化或第一次使用時被建立,而後被全部的線程共享。假如把某個request/session做用域的對象意外注入到singleton對象中,將可能產生致命的應用錯誤,甚至致使數據庫的錯亂。

在Webx中,這樣作是能夠的!奧祕在於Request Contexts服務對上表所列的這些短時間對象做了特殊的處理,使它們能夠被注入到singleton對象中。事實上,被注入的只是一個「空殼」,真正的對象是在被訪問到的時候纔會從線程中取得的。

9、buffered緩存response中內存的實現原理

Webx支持用layout/screen/control等部件共同構成一個頁面。其中,每一個layout可包含一個screen和多個control,每一個screen可包含多個control,每一個control還能夠在包含其餘的control。

通常頁面好比經過out.println("

hello world

");就直接輸出了,爲了還能分開而後再一塊兒顯示呢。例如,一個screen中包含了一個control,那麼screen能夠得到它所調用的control的完整的渲染內容。

這個玄機就是靠來實現的。改變了response的輸出流,包括output stream和writer,使寫到輸出流中的內容被暫存在內存中。當須要時,能夠取得緩存中的全部內容。

Buffered機制會延遲服務器對用戶的響應,因此某些場景須要關閉該服務。

10、表單驗證的模板

該文件form.xml位於WEB-INF的每一個子目錄中,用於表單的驗證

【重要】WebX框架解析及使用教程之一
 

11、Eclipse中開發Webx應用

(1)Webx工程目錄結構 

src\main:存放開發代碼

src\test:存放開發自測代碼,如單元測試代碼

main\java:存放java代碼

main\resources:存放資源定義文件

main\webapp:web應用配置文件

webapp目錄包含(舉例):

【重要】WebX框架解析及使用教程之一

1)子應用模板目錄admin、home、store、user,每一個模板目錄又由layout、control、screen三個子目錄組成,包含對應的模板文件(.vm文件)

2)通用模板目錄common

3)WEB-INF目錄

這是java web應用必備的配置目錄,包含了web.xml(java web應用必備的配置文件)、webx.xml(webx配置文件)、日誌配置文件(log4j.xml、logback.xml)、子應用配置文件(webx-admin.xml、webx-home.xml、webx-store.xml、webx-user.xml);另外還有對應每一個子應用的文件夾,用於存放form定義文件(form.xml)和訪問權限定義文件(access.xml);common文件夾中的pipeline.xml和pipeline-exception.xml定義了相關的管道操做流程。

(2)頁面獲取JAVA層的數據PullTool

在velocity模板中使用pulltool方便咱們進行頁面輸出內容的控制,組織頁面的展現,或者是直接取得web層相關的一些對象,直接在vm中調用。由頁面拉動業務邏輯,獲取並控制須要展現的內容,而非應用程序推進push,這符合webx的頁面驅動的模式。

1)是否啓動pull服務:

 【重要】WebX框架解析及使用教程之一

在webx.xml文件中進行總的控制

2)指定獲取數據的JAVA處理模塊

【重要】WebX框架解析及使用教程之一   

指定了獲取的數據位於com.xx.web.ui.module.*

3)在/xx/templates/screen下建立testMain.vm(M須要大寫)文件,內容以下:

  【重要】WebX框架解析及使用教程之一

4)在/src/main/java/com/web/ui/module/screen下建立文件TestMain.java(webx會自動匹配同名的文件),內容以下:

 

package com.yunos.tv.openbase.web.ui.module.screen;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.citrus.turbine.Context;

 

public class TestMain {

public void execute(HttpServletRequest request, HttpServletResponse response, Context context) throws Exception{

context.put("name", "Hugh");

}

 

}

 execute方法就是專門用來處理對應請求的,是webx潛規則的地方,它是頁面渲染以前處理的方法。

有些參數爲:public void execute(@Param("systemVersion") String systemVersion,HttpServletRequest request, HttpServletResponse response, Context context, Navigator nav),說明以下:第一個參數爲傳進來的信息,context對象負責頁面渲染時部分數據的修改。

 

(2)實現form表單功能

實現用戶帳號登錄的功能,若是用戶不輸入則提示用戶輸入相關信息,效果以下:【重要】WebX框架解析及使用教程之一


【重要】WebX框架解析及使用教程之一
 

其具體代碼以下:

login.vm文件:

【重要】WebX框架解析及使用教程之一
form.xml文件:

【重要】WebX框架解析及使用教程之一
 

關鍵點說明以下:

1.【重要】WebX框架解析及使用教程之一 

這表示提交以後執行的是LoginAction.java,這裏的value值login_action在程序內部會被處理成 LoginAction,所以這裏若是寫成value="LoginAction",結果是同樣的

 

2.【重要】WebX框架解析及使用教程之一

這裏提交後表示執行的方法是doUserInfoSumbit方法,若是你要執行其餘方法請修改name值name="event_submit_你的方法"

 

3.關聯form.xml:首先 #set ($group = $form.loginInfoGroup.defaultInstance)[固定寫法,loginInfoGroup對應form.xml中的services:group name="loginInfoGroup"],而後

 【重要】WebX框架解析及使用教程之一

name對應到form.xml中的規則,group.username.message就是須要顯示的錯誤信息。

 

4.$csrfToken.hiddenField是必需要添加的,防止跨站請求僞造攻擊。若是不添加的話,數據是不會從顯示層傳送給JAVA層的。

 

(3)實現form表單往JAVA層傳送數據功能

一、構造與表單對應的類LoginInfo:

package com.yunos.tv.openbase.biz.dataobject;

 

public class LoginInfo {

private String username;

private String password;

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

 

}

、1q     其中username和password的值須要和form.xml中定義的保持一致,不然二者沒法創建聯繫。

(2)   2.編輯業務功能LoginAction.java:

     

import com.alibaba.citrus.turbine.dataresolver.FormGroup;

import com.yunos.tv.openbase.biz.dataobject.LoginInfo;

 

public class LoginAction {

 

public void doUserInfoSumbit(@FormGroup("loginInfoGroup")LoginInfo userLoginInfo, HttpServletResponse response, Context context, Navigator nav) throws Exception{

System.out.println("hello");

System.out.println(userLoginInfo.getUsername());

   3.     

            3.若是數據模型LoginInfo和LoginAction不在同一個工程中,則LoginAction應該探測不到LoginInfo.class,須要LoginInfo先編譯生成class文件,而後LoginAction纔可使用LoginInfo類。在LoginInfo所在的工程使用mvn clean install命令從新進行編譯,而後在LoginAction刷新下引入該類。

相關文章
相關標籤/搜索