Junky's IT Notebook

          統(tǒng)計(jì)

          留言簿(8)

          積分與排名

          WebSphere Studio

          閱讀排行榜

          評(píng)論排行榜

          輕松進(jìn)行Java Portlets--開發(fā)基于JSR 168的開發(fā)和部署(轉(zhuǎn))

          作者:Prakash Malani


            Portlet是生成片段(遵守特定規(guī)范的標(biāo)記語言(如HTML、XML)的片段)的Web組件。片段再合成一個(gè)完整的文檔。本文介紹了關(guān)于Java Portlet的Java Specification Request (JSR) 168規(guī)范。它說明了如何使用BEA WebLogic Workshop 8.1 SP2來創(chuàng)建Java Portlet,以及如何將這些portlet部署到BEA WebLogic Portal 8.1 Sp2上。我將介紹一些關(guān)鍵概念,如門戶、桌面和portlet,并詳細(xì)描述多種portlet模式和窗口狀態(tài)。我還將介紹如何使用Workshop來設(shè)計(jì)、實(shí)現(xiàn)、配置和執(zhí)行portlet。


            JSR 168定義了有關(guān)Java Portlet的規(guī)范。門戶是一個(gè)Web應(yīng)用程序和一個(gè)portlet的聚合。Portlet容器運(yùn)行portlet,并管理它們的生命周期。JSR 168定義了portlet與portlet容器之間的契約,它沒有定義portlet容器與門戶之間的契約。門戶的實(shí)現(xiàn)留給了門戶供應(yīng)商。

            BEA WebLogic門戶
            BEA WebLogic Portal (8.1 SP2)的當(dāng)前版本支持不同類型的portlet:JSP/HTML portlet、Java PageFlow portlet、Struts portlet和Java portlet,將來還會(huì)支持其他portlet,如Web Services for Remote Portlets (WSRP)。我們將著重介紹Java portlet。

            WebLogic Portal提供了JSR 168中未描述的門戶功能,包括但不限于:書和頁面中portlet的組織、多渠道支持和使用skin、skeleton和shell定制。

            為了能夠繼續(xù)下去,在進(jìn)行下一部分之前,請(qǐng)先完成以下內(nèi)容:
             ·使用WebLogic Domain Configuration Wizard創(chuàng)建一個(gè)門戶域(如JSR168PortalDomain)。
             ·使用WebLogic Workshop創(chuàng)建一個(gè)使用上面所建立域的門戶應(yīng)用程序(如JSR168PortalApp)。
             ·在門戶應(yīng)用程序內(nèi)創(chuàng)建一個(gè)門戶Web項(xiàng)目(如JSR168PortalWebProject)。
             ·在門戶Web項(xiàng)目中創(chuàng)建一個(gè)WebLogic Portal .portal文件(如JSR168.portal)。
             ·啟動(dòng)服務(wù)器實(shí)例。

            創(chuàng)建您的第一個(gè)Java Portlet
            下面的步驟描述了如何創(chuàng)建您的第一個(gè)JSR 168 portlet。
            ·在門戶Web項(xiàng)目(如JSR168PortalWebProject)中,使用WebLogic Workshop為portlet(入FirstPortlet)創(chuàng)建一個(gè)新文件夾。
            ·在新文件夾內(nèi)使用Wizard通過創(chuàng)建相應(yīng)的.portlet文件創(chuàng)建一個(gè)新portlet(如Firstportlet)。
            ·選擇portlet類型為Java Portlet。
            ·指定標(biāo)題(如First)。
            ·指定定義標(biāo)簽(如first)。
            ·指定類名稱(如com.malani.examples.portlets.jsr168.FirstPortlet)。
            ·打開門戶(如JSR168.portal)。
            ·將portlet(如Firstportlet)拖放到門戶中的頁面上(如JSR168.portal)。
            ·運(yùn)行.portal文件進(jìn)行測(cè)試。

            您的第一個(gè)JSR 168 portlet已經(jīng)成功運(yùn)行了!但向?qū)г诒澈笞髁诵┦裁茨兀?br>  ·它創(chuàng)建了一個(gè)特定于WebLogic Workshop和WebLogic Portal的.portlet文件。.portlet文件構(gòu)成了與特定于Workshop和WebLogic Portal的.portal文件的契約。
            ·向?qū)?chuàng)建了一個(gè).java文件(如com.malani.examples.portlets.jsr168.FirstPortlet.java),該文件放置在WEB-INF/src目錄中。
            ·向?qū)?chuàng)建了一個(gè)WEB-INF/portlet.xml配置文件,并為portlet在文件中插入了一個(gè)條目。該portlet的條目看上去如下:

          <portlet>
          <description>Description goes here</description>
          <portlet-name>first</portlet-name>
          <portlet-class>com.malani.examples.portlets.jsr168.FirstPortlet
          </portlet-class>
          <portlet-info>
          <title>First</title>
          </portlet-info>
          </portlet>


            Java Portlet類
            在該示例中,向?qū)傻腜ortlet Java文件擴(kuò)展了javax.portlet.GenericPortlet類。GenericPortlet類實(shí)現(xiàn)了javax.portlet.Portlet接口。圖1是一個(gè)Unified Modeling Language (UML)類圖,描述了這些關(guān)系。通過直接實(shí)現(xiàn)portlet接口,可以編寫一個(gè)portlet。然而,GenericPortlet是一個(gè)創(chuàng)建portlet的更方便方法。首先,我們看一下portlet生命周期、portlet模式和window狀態(tài)。


          圖 1

            Portlet生命周期
            為了成功地創(chuàng)建portlet,您必須遵照portlet生命周期。javax.portlet.Portlet接口中的方法定義了該生命周期,這些生命周期方法是init()、render()、processAction()和destroy()。當(dāng)部署portlet的實(shí)例時(shí)調(diào)用init()方法。它用于獲得所需的任何昂貴資源(如后臺(tái)連接),并執(zhí)行其他一次性活動(dòng)。當(dāng)portlet的實(shí)例被撤銷部署時(shí),使用destroy()方法來釋放這些資源。

            Portlet規(guī)范清晰區(qū)別render請(qǐng)求和動(dòng)作請(qǐng)求。圖2描述了portlet請(qǐng)求和響應(yīng)的一個(gè)UML類圖。門戶頁面上的render請(qǐng)求會(huì)導(dǎo)致對(duì)所頁面上的每個(gè)portlet上調(diào)用render()方法,當(dāng)用戶在特定portlet上調(diào)用某個(gè)動(dòng)作(通常是HTML表單提交)時(shí),將會(huì)調(diào)用該portlet的processAction()方法。這樣,用戶的動(dòng)作請(qǐng)求轉(zhuǎn)換為processAction()方法的一次調(diào)用和render()方法的多次調(diào)用。


          圖 2

            圖3是一個(gè)序列圖,說明了調(diào)用processAction()方法的效果,以及為同一頁面上的portlet進(jìn)行后續(xù)render()方法的調(diào)用。關(guān)于更多信息,請(qǐng)參閱關(guān)于處理動(dòng)作的一節(jié)。


          圖 3

            有兩種重載的init()方法,一個(gè)沒有參數(shù),另一個(gè)有一個(gè)javax.portlet.PortletConfig類的實(shí)例。注意:關(guān)于init(PortletConfig)有一個(gè)特殊的caveat。調(diào)用super.init(aPortletConfig)失敗將導(dǎo)致一個(gè)NullPointerException。所包含的源代碼示例中的Init portlet說明了這種行為(源代碼可以在www.sys-con.com/weblogic/source.cfm中找到)。

            Portlet模式
            JSR 168定義了三種Portlet模式:VIEW、EDIT和HELP。一個(gè)portlet實(shí)例在任何時(shí)候都可以恰巧在一種 portlet模式下。其他自定義portlet模式(如配置和源)都是可能的。VIEW模式是默認(rèn)的模式。Portlet規(guī)范建議EDIT模式允許portlet用戶定制portlet實(shí)例,以及HELP模式顯示關(guān)于portlet的用法信息。Portlet必須支持VIEW模式,但在portlet中對(duì)EDIT模式和HELP模式的支持是可選的。例如,portlet First portlet示例不支持EDIT模式和HELP模式。

            window狀態(tài)
            JSR 168定義了三種Window狀態(tài):NORMAL、MINIMIZED和MAXIMIZED。Portlet實(shí)例任何時(shí)候都可以恰好是一種window狀態(tài)。其他自定義window狀態(tài)(如半頁)也是可能的。在NORMAL狀態(tài)下,portlet占了屏幕區(qū)的一小部分。屏幕狀態(tài)與其他portlet共享。在MINIMIZED狀態(tài)下,portlet的內(nèi)容被隱藏。在MAXIMIZED狀態(tài)下,portlet的內(nèi)容占屏幕區(qū)的大部分。其他共享同一頁面的portlet在MAXIMIZED狀態(tài)下被隱藏。例如,portlet First示例支持所有三種window狀態(tài)。

            GenericPortlet類
            您創(chuàng)建的大多數(shù)portlet將會(huì)擴(kuò)展javax.portlet.GenericPortlet類,而不是直接實(shí)現(xiàn)javax.portlet.Portlet接口。GenericPortlet類實(shí)現(xiàn)了render()方法。如果portlet的window狀態(tài)被最小化,那么render()方法不能做任何事情。如果portlet的window狀態(tài)不是最小化,那么render()方法設(shè)置在portlet.xml文件中指定的標(biāo)題,并調(diào)用doDispatch()方法。根據(jù)Portlet模式, doDispatch()方法適當(dāng)?shù)卣{(diào)用doView()、doEdit()和doHelp()方法。這樣,由于GenericPortlet類幫助實(shí)現(xiàn)render()方法,并且提供doView()、doEdit()和doHelp()方法來覆蓋,因此GenericPortlet類比Portlet接口更便于擴(kuò)展。

            考慮一下First portlet示例。FirstPortlet類擴(kuò)展了GenericPortlet,F(xiàn)irstPortlet改寫了doView()方法。

          public void doView(RenderRequest request, RenderResponse response)
          throws PortletException, IOException
          {
          response.setContentType("text/html");
          response.getWriter().write("<p>Hello World</p>");
          }


            注意:調(diào)用setContentType()方法前調(diào)用getWriter()方法會(huì)導(dǎo)致java.lang.IllegalStateException。

            實(shí)現(xiàn)Portlet模式
            VIEW模式是強(qiáng)制的,但EDIT和HELP模式是可選的。為了實(shí)現(xiàn)EDIT和HELP portlet模式,需要在portlet類中實(shí)現(xiàn)適當(dāng)?shù)膁oEdit()和doHelp()方法。請(qǐng)參考包含在源代碼示例(本文的源代碼可以在www.sys-con.com/wldj/sourcec.cfm找到)中的portlet Mode。此外,必須在portlet.xml中如下配置各模式:

          <supports>
          <mime-type>text/html</mime-type>
          <portlet-mode>edit</portlet-mode>
          <portlet-mode>help</portlet-mode>
          </supports>


            注意:修改portlet.xml配置文件,但不實(shí)現(xiàn)portlet類中的相應(yīng)方法,會(huì)導(dǎo)致javax.portlet.PortletException。

            實(shí)現(xiàn)window狀態(tài)
            JSR 168沒有描述禁用window狀態(tài)支持的方法。然而,WebLogic Portal實(shí)現(xiàn)了對(duì)它們的禁用。為了禁用portlet對(duì)window狀態(tài)的支持,需要在weblogic-portlet.xml文件中排除window狀態(tài):

          <portlet>
          <portlet-name>state</portlet-name>
          <supports>
          <mime-type>text/html</mime-type>
          <excluded-window-state>minimized</excluded-window-state>
          <excluded-window-state>maximized</excluded-window-state>
          </supports>
          </portlet>


            請(qǐng)參考源代碼示例中的portlet State。

            包含JavaServer Pages (JSPs)
            考慮portlet First的doView()方法,該方法獲得了Writer的實(shí)例,并直接輸出HTML片段。由于多種原因(如為了達(dá)到Java邏輯與HTML視圖表現(xiàn)的分離),往往不推薦輸出直接的HTML片段。推薦的方法是使用JSP來顯示視圖。portlet類中的方法執(zhí)行業(yè)務(wù)邏輯、設(shè)置render參數(shù)以及包含JSP。為了包含一個(gè)特定的JSP,應(yīng)首先獲得PortletContext。從PortletContext實(shí)例中,通過調(diào)用getRequestDispatcher()方法獲得一個(gè)PortletRequestDispatcher的實(shí)例。通過調(diào)用include()方法來包含JSP。例如:

          // execute the necessary logic here...
          PortletRequestDispatcher aDispatcher =
          getPortletContext().getRequestDispatcher(
          "/IncludePortlet/includeView.jsp"
          );
          aDispatcher.include(aRequest, aResponse);


            注意:在執(zhí)行render()方法時(shí),portlet可能只使用一個(gè)PortletRequestDispatcher對(duì)象。
            請(qǐng)參考包含在源代碼中的portlet Include。JSP頁面(如includeView.jsp)不包含根HTML標(biāo)簽(如<html>、<title>和<body>),因?yàn)檫@些標(biāo)簽由門戶框架提供。JSP頁面只包含顯示portlet所必需的HTML片段。

            處理動(dòng)作
            在一個(gè)標(biāo)準(zhǔn)的Web應(yīng)用程序中,一個(gè)HTML表單提交將導(dǎo)致執(zhí)行一些業(yè)務(wù)邏輯。業(yè)務(wù)處理的結(jié)果,要么作為屬性而被設(shè)置在請(qǐng)求或會(huì)話中并轉(zhuǎn)發(fā),要么包含到下一個(gè)JSP。

            在一個(gè)JSR 168 portlet中,一個(gè)HTML表單的動(dòng)作URL應(yīng)該是什么樣呢?JSR 168定義了一個(gè)JSP標(biāo)簽庫,稱為portlet taglib。HTML表單的動(dòng)作URL可以使用actionURL portlet標(biāo)簽生成。例如(請(qǐng)參考favoriteColorEdit.jsp文件):

          <form action="<portlet:actionURL/>" method="post">
          ...
          </form>


            提交該HTML表單將會(huì)導(dǎo)致調(diào)用portlet的processAction(ActionRequest aRequest, ActionResponse aResponse)方法。像通常一樣,可以通過調(diào)用request對(duì)象的getParameter()方法來獲得表單參數(shù)。注意:通過提交表單調(diào)用動(dòng)作,但portlet中卻沒有processAction()方法,將會(huì)導(dǎo)致javax.portlet.PortletException。

            processAction()方法設(shè)置response對(duì)象中的值。不要使用ActionRequest或ActionResponse對(duì)象的setAttribute()方法。值不會(huì)從processAction()傳遞到render()方法,而且在JSP中是不可用的。相反要使用ActionResponse對(duì)象的setRenderParameter()方法。這些render參數(shù)將對(duì)所有后續(xù)render請(qǐng)求可用,這一點(diǎn)與典型的Web應(yīng)用程序請(qǐng)求屬性很不相同。典型的Web application請(qǐng)求屬性只對(duì)于一個(gè)請(qǐng)求可用。另一方面,render請(qǐng)求參數(shù)對(duì)于許多后續(xù)render請(qǐng)求可用。render參數(shù)保持可用直到值被動(dòng)作的重新執(zhí)行顯式地修改或刪除。

            考慮portlet FavoriteColor。它在VIEW模式顯示了一個(gè)用戶偏好的顏色,但是可以在EDIT模式下更改。在EDIT模式下提交偏好的顏色選擇將調(diào)用processAction()方法。該方法獲得偏好的顏色請(qǐng)求參數(shù),并將其設(shè)置為render參數(shù)。這樣,偏好的的顏色render參數(shù)將在所有后續(xù)render請(qǐng)求中都可用。

            所呈現(xiàn)的參數(shù)是怎樣顯示在JSP上的呢?應(yīng)使用來自portlet標(biāo)簽庫的defineObjects標(biāo)簽來定義portlet對(duì)象。該標(biāo)簽使renderRequest、renderResponse和portletConfig portlet對(duì)象在頁面中可用。參數(shù)通過調(diào)用renderRequest對(duì)象的getParameter()方法來顯示。請(qǐng)參考與所包含的源代碼示例中的favoriteColorView.jsp。

            portlet FavoriteColor也展示了其他概念。第一個(gè)是如何在processAction()方法中用編程的方法改變portlet模式。調(diào)用ActionResponse對(duì)象的setPortletMode()方法來修改portlet模式。第二個(gè)概念是如何使用一個(gè)HTML鏈接來修改portlet模式。該鏈接使用來自portlet標(biāo)簽庫的renderURL標(biāo)簽生成。根據(jù)希望的portlet模式指定portletMode屬性的值。請(qǐng)參考源代碼示例中的FavoriteColorPortlet類和favoriteColorView.jsp頁面。

            Portlet Preferences
            Portlet Preferences(Portlet首選項(xiàng))是portlet的基本配置數(shù)據(jù)。一個(gè)preference是一個(gè)“名稱和值”對(duì)。名稱的類型是一個(gè)字符串,而值的類型是字符串或字符串?dāng)?shù)組。Portlet Preference不適于存儲(chǔ)任意數(shù)據(jù)。portlet容器為portlet preferences提供持久性。在WebLogic Portal中,preference的持久性只在下面兩個(gè)條件都為真時(shí)才起作用:
            ·門戶運(yùn)行在桌面中,而不是DOT門戶模式。
            ·用戶已經(jīng)登錄。

            桌面與DOT門戶模式
            在WebLogic Workshop中創(chuàng)建.portal文件時(shí),像書、頁面和portlet等項(xiàng)都可以被拖放到.portal文件中,.portal文件能夠直接從Workshop內(nèi)運(yùn)行。然而,某些功能,如preferences的存儲(chǔ),在這種DOT門戶模式下運(yùn)行時(shí)是不可用的(DOT門戶模式也稱為單文件模式(Single File Mode))。

            其他模式稱為桌面模式。創(chuàng)建一個(gè)門戶時(shí)使用Portal Administrator。在門戶內(nèi),一個(gè)桌面被創(chuàng)建。像圖書、頁面和portlet等項(xiàng)被創(chuàng)建,并放置在桌面中。在這種模式下,某些功能,像preferences的存儲(chǔ),是可用的(桌面模式也被稱為流模式(Streamed Mode))。

          在繼續(xù)討論前,先創(chuàng)建一個(gè)桌面:
            啟動(dòng)Portal Administration(譬如,http://localhost:7001/JSR168PortalAppAdmin/)。一種啟動(dòng)Portal Administration的方法是直接從Workshop中啟動(dòng)。選擇Portal菜單,選中Portal Administration菜單項(xiàng)。
            ·登錄進(jìn)Portal Administration。
            ·創(chuàng)建一個(gè)新門戶(譬如,JSR168)。
            ·在門戶中,創(chuàng)建一個(gè)新桌面(如d1)。
            ·將LoginPortlet添加到桌面的一個(gè)頁面中。
            ·將ContactPortlet添加到桌面的一個(gè)文件中。

            Portlet Preferences示例
            Contact portlet演示了Portlet Preferences。Portlet Preferences可以是靜態(tài)的或動(dòng)態(tài)的。靜態(tài) preferences與portlet一起在portal.xml文件中指定。例如,ContactPortlet具有一個(gè)成為contact-preference的 preferences。contact-preference的默認(rèn)值也被指定:

          <portlet-preferences>
          <preference>
          <name>contact-preference</name>
          <value>Email</value>
          </preference>
          </portlet-preferences>


            動(dòng)態(tài) preferences不在portlet.xml配置文件中預(yù)定義。當(dāng)portlet運(yùn)行時(shí),這些preferences被存儲(chǔ)和讀取。在運(yùn)行期間,一個(gè)javax.portlet.PortletPreferences接口的實(shí)例包含這些preferences。該實(shí)例通過調(diào)用PortletRequest對(duì)象的getPreferences()方法獲得。特定preferences的值通過調(diào)用preferences實(shí)例上的getValue()方法來獲得。

            調(diào)用preferences實(shí)例的setValue()方法會(huì)更新一個(gè)preferences值。然而,需要一個(gè)額外的步驟來提交這些修改。preferences實(shí)例的store()方法被調(diào)用來使preferences持久化。preferences只能在processAction()方法中進(jìn)行修改。如果在processAction()方法中沒有調(diào)用store()方法,任何對(duì)preferences實(shí)例的修改都會(huì)被丟棄。注意:就如前面提到的,如果用戶沒有登錄或門戶處于DOT門戶模式,那么調(diào)用store()方法將會(huì)導(dǎo)致一個(gè)運(yùn)行時(shí)異常。

            在portlet和servlet之間有很多相似點(diǎn)。然而,它們也存在著重要區(qū)別。portlet規(guī)范建立在servlet規(guī)范之上。portlet容器存在于servlet容器中。就像servlet部署在一個(gè)Web應(yīng)用程序中,portlet也是如此。Servlet和Web應(yīng)用程序使用portlet.xml文件進(jìn)行配置。一個(gè)servlet具有顯式的生命周期:init()、doGet()、doPost()等。類似地,一個(gè)portlet也具有顯式的生命周期:doView()、doEdit()、processAction()等。servlet和portlet類的方法必須以安全線程的方式編碼。

            然而,也存在著重要的區(qū)別。Servlet被允許進(jìn)行include、forward和redirect操作;然而portlet只被允許進(jìn)行include操作。Servlet能夠呈現(xiàn)一個(gè)完整的頁面,但portlet只提交頁面片段。portlet具有嚴(yán)格定義的portlet模式和Window狀態(tài),這方面不像servlet。Portlet具有更正式的請(qǐng)求,對(duì)render請(qǐng)求和動(dòng)作請(qǐng)求進(jìn)行處理,它們也具有preferences。portlet并不是servlet!

            結(jié)束語
            本文通過使用一個(gè)簡單的向?qū)枋鰌ortlet的創(chuàng)建而開始,并說明了portlet的生命周期以及portlet類實(shí)現(xiàn)的內(nèi)部工作方式,描述了portlet.xml配置文件和相應(yīng)的weblogic-portlet.xml配置文件的結(jié)構(gòu)和語義。對(duì)各種概念,如portlet模式和window狀態(tài),本文也進(jìn)行了解釋。本文演示了portlet標(biāo)簽庫的用法和portlet中的表單處理。最后,我介紹了如何使用portletpreferences。理解了本文所介紹的這些知識(shí)和概念,您就可以在創(chuàng)建和部署自己的強(qiáng)大portlet的道路上前進(jìn)了。

            致謝
            感謝Subbu Allamaraju、Max Cooper、Steve Ditlinger、David Lu、Roshni Malani和Alex Toussaint,他們仔細(xì)閱讀了這篇文章,并提供了有價(jià)值的反饋意見。

            參考資料
            · 要討論這篇文章、并提問問題,從這里開始: www.bartssandbox.com。需要免費(fèi)成員資格。
            · 下載、閱讀JSR 168:www.jcp.org/en/jsr/detail?id=168
            · WebLogic Portal文檔的起始點(diǎn):e-docs.bea.com/wlp/docs81/index.html
            · 建立Workshop Help的Java Portlet部分:e-docs.bea.com/workshop/docs81/doc/en/core/index.html
            · 用WebLogic Portal 8.1開發(fā)JSR 168 Portlet:dev2dev.bea.com/products/wlportal81/articles/JSR168.jsp
            · Web Services for Remote Portlets (WSRP)規(guī)范:www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp
            · 嘗試一下WSRP:dev2dev.bea.com/codelibrary/code/wsrp_supportkit.jsp
            · Single File Mode和Streamed Rendering Mode:單擊這里
            · 有關(guān)Portlet規(guī)范上的文章:
          - 介紹Portlet規(guī)范,第1部分:
          www.javaworld.com/javaworld/jw-08-2003/jw-0801-portlet_p.html
          -介紹Portlet規(guī)范,第2部分:
          www.javaworld.com/javaworld/jw-09-2003/jw-0905-portlet2_p.html
            · 對(duì)JSR 168白皮書的介紹:單擊這里!
            · Java Passion Portlet演講筆記:www.javapassion.com/j2eeadvanced/Portlet4.pdf

            源代碼
            源代碼-Zip文件
            英文原文:http://www.sys-con.com/story/?storyid=45565&DE=1

           作者簡介
          icon
          Prakash Malani
          Prakash Malani 在架構(gòu)、設(shè)計(jì)和開發(fā)軟件方面經(jīng)驗(yàn)豐富。他在許多應(yīng)用領(lǐng)域從事過軟件開發(fā),比如娛樂、金融、零售、醫(yī)學(xué)、通信和交互式電視。他喜歡實(shí)踐和研究先進(jìn)的技術(shù),比如Java 2 Enterprise Edition (J2EE)、Unified Modeling Language (UML)和eXtensible Markup Language (XML)。他還在加利福尼亞州立理工大學(xué)波莫那校區(qū)等機(jī)構(gòu)講授最佳實(shí)踐和設(shè)計(jì)模式。他在業(yè)界的著名出版物上發(fā)表過許多文章,比如JavaWorld和WebLogic Developers Journal。當(dāng)前,他正在幫助組織Los Angeles BEA Users Group (LABEAUG)。
          dot dot dot

          dot
            作者其它文章

          posted on 2007-06-15 10:39 junky 閱讀(712) 評(píng)論(0)  編輯  收藏 所屬分類: portal

          主站蜘蛛池模板: 朔州市| 台中县| 慈利县| 白河县| 江津市| 阳原县| 哈巴河县| 博野县| 五莲县| 屯门区| 响水县| 宿松县| 会同县| 略阳县| 当涂县| 衡南县| 武宣县| 彰化市| 辽中县| 新民市| 富蕴县| 云梦县| 巩义市| 建宁县| 徐水县| 班戈县| 崇信县| 麻栗坡县| 黄梅县| 祁阳县| 遵化市| 江北区| 马公市| 池州市| 贵德县| 庆元县| 阿合奇县| 正镶白旗| 从化市| 冕宁县| 鄂托克前旗|