本文以一個(gè)教學(xué)網(wǎng)站的建設(shè)思路為例,探討利用J2EE技術(shù)和WebSphere產(chǎn)品構(gòu)建網(wǎng)站的模式和方法。

二、設(shè)計(jì)網(wǎng)站系統(tǒng)

我們的樣例是一個(gè)教學(xué)網(wǎng)站系統(tǒng),它的軟件" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > 看看阿里13年后端開(kāi)發(fā)大佬如何利用J2EE模式構(gòu)建網(wǎng)站

看看阿里13年后端開(kāi)發(fā)大佬如何利用J2EE模式構(gòu)建網(wǎng)站

時(shí)間:2023-08-15 00:03:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-08-15 00:03:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

看看阿里13年后端開(kāi)發(fā)大佬如何利用J2EE模式構(gòu)建網(wǎng)站:一、前言

本文以一個(gè)教學(xué)網(wǎng)站的建設(shè)思路為例,探討利用J2EE技術(shù)和WebSphere產(chǎn)品構(gòu)建網(wǎng)站的模式和方法。

二、設(shè)計(jì)網(wǎng)站系統(tǒng)

我們的樣例是一個(gè)教學(xué)網(wǎng)站系統(tǒng),它的軟件包括WebSphere Application Server應(yīng)用服務(wù)器軟件V4.0、WSAD開(kāi)發(fā)工具和DB2數(shù)據(jù)庫(kù)(非商業(yè)用途),硬件為IBM xSeries服務(wù)器。在本文中,主要探討MVC的開(kāi)發(fā)模型和常用的J2EE模式,關(guān)于網(wǎng)站建設(shè)的其他細(xì)節(jié)就略過(guò)不提了。

(一)系統(tǒng)用例圖

分析網(wǎng)站的系統(tǒng)目標(biāo)后,我們首先具體化系統(tǒng)功能,形成一張用例圖,定義一系列的可重構(gòu)組件,以指導(dǎo)隨后的開(kāi)發(fā)工作。








圖1 Use Case picture

(二)組件化設(shè)計(jì)

在構(gòu)造網(wǎng)站系統(tǒng)時(shí),我們把每層的系統(tǒng)想象成擁有多個(gè)"槽"的裝置,開(kāi)發(fā)人員可以向槽中插入組件以擴(kuò)大其能力,也可以通過(guò)繼承或其他機(jī)制具體化組件系統(tǒng)。這些組件可以是開(kāi)發(fā)人員為該應(yīng)用系統(tǒng)開(kāi)發(fā)的,也可以是以前開(kāi)發(fā)好的復(fù)用組件。在這種分層體系結(jié)構(gòu)中,每個(gè)應(yīng)用系統(tǒng)都表示為一個(gè)單獨(dú)的系統(tǒng)。每個(gè)系統(tǒng)都采用組件構(gòu)造。每個(gè)組件系統(tǒng)又可以通過(guò)其他下層組件系統(tǒng)構(gòu)造。重構(gòu)人員采用一組與特定應(yīng)用系統(tǒng)領(lǐng)域和業(yè)務(wù)有關(guān)的組件或頂層中的組件系統(tǒng)來(lái)構(gòu)造每個(gè)應(yīng)用系統(tǒng)。

結(jié)合J2EE,讓我們首先了解J2EE體系中的組件構(gòu)成情況,如圖2所示。








圖2 J2EE組件打包策略

在上圖中可以看出,不同的組件歸檔到不同的文件包中,這樣就保證了一個(gè)組件的"插拔"不會(huì)影響到其它的組件。根據(jù)應(yīng)用系統(tǒng)組件的功能,我們可以把它們分為動(dòng)態(tài)組件和靜態(tài)組件。靜態(tài)的組件包含網(wǎng)頁(yè)文件,主要用于放置教學(xué)資料和參考文章。動(dòng)態(tài)組件則包括各種功能模塊,如論壇系統(tǒng)、模擬測(cè)驗(yàn)系統(tǒng)等。

應(yīng)用系統(tǒng)組件之下是于特定業(yè)務(wù)有關(guān)的組件。在這里,我們可以添加非Java編寫(xiě)的一些程序,用于處理特定內(nèi)容下的操作,比如模擬測(cè)驗(yàn)系統(tǒng)中的出題模塊。當(dāng)然,要考慮到上層組件調(diào)用的正面接口問(wèn)題。對(duì)于這層組件,我們能夠隨時(shí)替換,只要其提供的數(shù)據(jù)符合上級(jí)正面的要求。

以上兩級(jí)組件之下是J2EE應(yīng)用服務(wù)器和操作系統(tǒng),整體如圖3所示。





圖3 計(jì)算機(jī)組成原理網(wǎng)站系統(tǒng)組件架構(gòu)圖

(三)利用J2EE模式開(kāi)發(fā)組件系統(tǒng)

下面著重介紹開(kāi)發(fā)過(guò)程中使用的J2EE模式,這些模式都是通用類型的。

本系統(tǒng)采用MVC開(kāi)發(fā)模型,即Model-View-Controller。Model是指應(yīng)用程序的數(shù)據(jù),以及對(duì)這些數(shù)據(jù)的操作;View是指用戶界面;Controller負(fù)責(zé)用戶界面和程序數(shù)據(jù)之間的同步。這種模型的好處在于分離不同功能的代碼,便于以后的維護(hù),還有利于在項(xiàng)目小組內(nèi)按照小組成員各自的擅長(zhǎng)進(jìn)行分工,有利于三個(gè)部分并行開(kāi)發(fā)、加快項(xiàng)目進(jìn)度。

為了使各開(kāi)發(fā)人員協(xié)調(diào)一致,為其他組件提供一致和標(biāo)準(zhǔn)的正面,增強(qiáng)系統(tǒng)的可維護(hù)性和可復(fù)用性,我們廣泛采用了SUN公司提出的基于MVC的設(shè)計(jì)模式。

圖4是用戶注冊(cè)模塊的UML圖,我們將結(jié)合這個(gè)模塊具體闡述各模式的特點(diǎn)和在本系統(tǒng)中的實(shí)際應(yīng)用。







明確了所采用的體系和模式,下面具體設(shè)計(jì)類的屬性和方法,通過(guò)設(shè)計(jì)完善的接口和繼承、重載等方法進(jìn)行重構(gòu)。模塊的UML的類圖表示如下:







模塊的UML的類圖

結(jié)合上圖,讓我們看看這個(gè)模塊中都運(yùn)用了哪些模式。

1. 表示層模式

系統(tǒng)的表示層集中了MVC模式中的View與Controller。該系統(tǒng)用JSP代表View,用Servlet代表Controller。在Controller這一模塊中,又采用了視圖助手、分發(fā)者與值對(duì)象模式,以增強(qiáng)系統(tǒng)的模塊化,提高維護(hù)性。

(1)前端控制器

控制器通常表現(xiàn)為Servlet形式,其UML表示如下:







根據(jù)Model-View-Controller的開(kāi)發(fā)思想,使用控制器作為處理請(qǐng)求的最初聯(lián)系點(diǎn)。該控制器管理著請(qǐng)求的處理,包括調(diào)用安全服務(wù),比如驗(yàn)證和授權(quán)、委托業(yè)務(wù)處理、管理合適的視圖選擇、處理錯(cuò)誤,以及管理內(nèi)容創(chuàng)建邏輯的選擇。也可以把前端控制器看成一個(gè)觸發(fā)器,由它來(lái)啟動(dòng)流程。

下面是功能代碼的樣本。其中出現(xiàn)的RegisterHelper、Command等類,接下來(lái)會(huì)有詳細(xì)介紹。

public void performTask(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { RegisterHelper rh=new RegisterHelper(request,response);//啟動(dòng)注冊(cè)視圖助手 Command command=rh.getCommand();//由視圖助手中獲得并初始化Command CustomerBean cb=rh.getCustomerBean();//由視圖助手中獲得并初始化值對(duì)象 request.setAttribute("customerbean",cb); String dispatcher=rh.getDispatcher();//由視圖助手中獲得并初始化分發(fā)者 request.setAttribute("type",rh.getType());//設(shè)置上下文屬性 try { command.execute((Helper)rh);//執(zhí)行業(yè)務(wù)代碼 } catch(javax.ejb.DuplicateKeyException de) { request.setAttribute("errorbean",new ErrorBean("對(duì)不起,已經(jīng)有人注冊(cè)了該用戶名!"));//注冊(cè)重名處理 dispatch(request,response,dispatcher);//分發(fā)并移交控制權(quán) return; } catch(Exception e) { request.setAttribute("errorbean",new ErrorBean("對(duì)不起,數(shù)據(jù)庫(kù)出錯(cuò)!"));//出錯(cuò)處理 dispatch(request,response,dispatcher); return; } dispatch(request,response,dispatcher); }優(yōu)點(diǎn):通過(guò)集中化決策點(diǎn)和控制,控制器有助于減少嵌入在JSP中Java代碼(Scriptlet)的數(shù)量,保持View功能的純潔性。它的位置如圖5中Controller所示。

表示層更改經(jīng)常發(fā)生,而且當(dāng)業(yè)務(wù)數(shù)據(jù)訪問(wèn)邏輯和表示格式化邏輯被混雜時(shí),表示層更改很難開(kāi)發(fā)和維護(hù)。這使系統(tǒng)靈活性更差,更缺乏可用性,而且對(duì)變化的適應(yīng)性更弱。







視圖包含格式化代碼,把其處理責(zé)任委托給其助手類。助手也存儲(chǔ)該視圖的中間數(shù)據(jù),如表單、URL參數(shù)等,并且充當(dāng)業(yè)務(wù)數(shù)據(jù)適配器。

下面是功能代碼的樣本。

public class RegisterHelper implements Helper { static String dispatcher = "RegisterDispatcher"; private CustomerBean customer = null; private String type = null; public RegisterHelper( javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) { setType(request); setCustomerBean(request); } /** * 定義頁(yè)面類型:HTML or XML */ public void setType(javax.servlet.http.HttpServletRequest request) { type = request.getParameter("type"); } /** * 獲取Command */ public Command getCommand() { RegisterCommand rc = new RegisterCommand(); return rc; } /** * 向值對(duì)象中填充數(shù)據(jù) */ public void setCustomerBean(javax.servlet.http.HttpServletRequest request) { customer = new CustomerBean(); customer.setUsername(request.getParameter("username")); customer.setPassword(request.getParameter("password")); customer.setEmail(request.getParameter("email")); customer.setTruename(request.getParameter("truename")); customer.setId(request.getParameter("id")); customer.setService(this.setService(request)); } /** * 獲取值對(duì)象 */ public CustomerBean getCustomerBean() { return this.customer; } /** * 獲取分發(fā)者 */ public String getDispatcher() { return this.dispatcher; } /** * 獲取類型 */ public String getType() { return type; }}優(yōu)點(diǎn):在助手中而不是在視圖中封裝業(yè)務(wù)邏輯會(huì)增強(qiáng)應(yīng)用程序的模塊化,并且更有利于組件重用。助手有大量的責(zé)任,包括收集視圖和控制需要的數(shù)據(jù),以及存儲(chǔ)中間模型。它的位置如圖5中Helper所示。

3)Command模式

Command中包含純業(yè)務(wù)代碼,如注冊(cè)、登陸、檢驗(yàn)等。在樣例模塊中,它的職責(zé)是將注冊(cè)信息傳遞給Entity Bean。







功能代碼如下所示:

public void execute(Helper helper) throws Exception { RegisterHelper rh = (RegisterHelper) helper;//獲取視圖助手 CustomerBean cb = rh.getCustomerBean();//從視圖助手中獲取值對(duì)象 ServiceLocator sl = ServiceLocator.getInstance();//初始化服務(wù)定位器 CustomersHome ch = (CustomersHome) sl.getHome(ServiceLocator.Services.CUSTOMERS);//從服務(wù)定位器中獲取Entity Bean本地接口 try { Customers customers = ch.create(cb);//將注冊(cè)信息導(dǎo)入數(shù)據(jù)庫(kù) } catch(javax.ejb.DuplicateKeyException e) { throw new javax.ejb.DuplicateKeyException(); } catch(Exception e) { throw e; } }(4)分發(fā)者模式

如果將表示化邏輯和業(yè)務(wù)邏輯混合在視圖中,會(huì)使系統(tǒng)可重用性和靈活性變差,而且一半還會(huì)使更改操作難以實(shí)施。分發(fā)者負(fù)責(zé)視圖管理和導(dǎo)航,選擇下一個(gè)視圖,并且提供分發(fā)資源控制的機(jī)制。分發(fā)者可以提供靜態(tài)的分發(fā),也能提供更高級(jí)的動(dòng)態(tài)分發(fā)機(jī)制。

在我們的項(xiàng)目中,由于涉及到PC用戶和移動(dòng)手機(jī)用戶的訪問(wèn),我們需要針對(duì)不同的用戶返回不同的結(jié)果頁(yè)面,因此分發(fā)者的存在就非常有必要。分發(fā)者表現(xiàn)為Servlet形式,它承接Controller的處理結(jié)果,并判斷用戶的類型,把正確的視圖返回給用戶。它的位置如圖5中Dispatcher所示。







功能代碼如下所示:

public void performTask( javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { String type=(String)request.getAttribute("type");//獲取頁(yè)面類型 isError=(request.getAttribute("errorbean")!=null)?true:false;//判斷是否出錯(cuò) String file=selectType(type,isError,response);//根據(jù)頁(yè)面類型和是否出錯(cuò)確定顯示頁(yè)面 getServletConfig().getServletContext().getRequestDispatcher(file).forward(request,response);//重定向到顯示頁(yè)面 } public String selectType(String str,boolean isError,javax.servlet.http.HttpServletResponse response) { if (str.equals("html")) {//HTML類型的頁(yè)面 if (isError) {//成功 System.out.println("Some error happens!"); return "register_error.jsp"; } else {//出錯(cuò) return "register_ok.jsp"; } } else {//WML手機(jī)頁(yè)面 if (isError) {//成功 System.out.println("Some error happens!"); return "wml/register_error.jsp"; } else {//出錯(cuò) response.setContentType("text/vnd.wap.wml;charSet=gb2312"); return "wml/register_ok.jsp"; } } }(5)復(fù)合視圖

復(fù)雜的Web頁(yè)面可以展示來(lái)自多個(gè)數(shù)據(jù)源的內(nèi)容,使用多個(gè)包含單顯示頁(yè)面的子視圖。同時(shí),具有不同技能的多個(gè)開(kāi)發(fā)人員可以參與這些Web頁(yè)面的開(kāi)發(fā)和維護(hù)。

因此,我們采用有多個(gè)原子視圖組成的復(fù)合視圖。模版中每個(gè)組件是動(dòng)態(tài)結(jié)合在一起的,并且頁(yè)面的布局是獨(dú)立于內(nèi)容進(jìn)行管理的。在我們的項(xiàng)目中,采用了<jsp:include page="***" flush="true">嵌入頁(yè)面,使導(dǎo)航欄和標(biāo)示獨(dú)立于各個(gè)頁(yè)面,使用戶能夠及時(shí)地看到任何變動(dòng),并使系統(tǒng)更改的代價(jià)降低到最小。

2. 業(yè)務(wù)層模式

(1)值對(duì)象

J2EE應(yīng)用程序把服務(wù)器端業(yè)務(wù)組件實(shí)現(xiàn)為Session Bean和Entity Bean。業(yè)務(wù)組件的一些方法可以向客戶端返回?cái)?shù)據(jù)。通常,客戶端需要多次調(diào)用業(yè)務(wù)對(duì)象的get/set方法直到獲得所有的屬性值。由于EJB的調(diào)用采用RMI-IIOP方式通過(guò)網(wǎng)絡(luò)進(jìn)行,這樣做大大延緩了業(yè)務(wù)層的處理速度,降低了效率。

為了解決這一問(wèn)題,我們使用值對(duì)象封裝業(yè)務(wù)數(shù)據(jù)。相應(yīng)的方法調(diào)用是設(shè)置和檢索值對(duì)象。當(dāng)客戶端向企業(yè)bean請(qǐng)求業(yè)務(wù)數(shù)據(jù)時(shí),該企業(yè)bean可以構(gòu)造值對(duì)象,用屬性值來(lái)填充,并且按照值把它傳遞給客戶端,這也符合EJB端粗粒度調(diào)用的需要。

值對(duì)象是可串行化的JavaBean對(duì)象。值對(duì)象類也可以提供接收所有必須的屬性以創(chuàng)建該值對(duì)象的構(gòu)造器。通常,值對(duì)象中的成員被定義為私有的,而其Get/Set方法則是公有的。

(2)服務(wù)定位器

J2EE客戶端與EJB組件進(jìn)行交互,這些組件提供業(yè)務(wù)服務(wù)和持久性能力。為了與它們交互,客戶端必須定位(或稱為查找)該服務(wù)組件,或創(chuàng)建一個(gè)新的組件。比如,EJB客戶端必須定位EJB的本地對(duì)象,然后客戶端使用該本地對(duì)象來(lái)查找某對(duì)象,或者創(chuàng)建或刪除一個(gè)或多個(gè)EJB。

這樣,對(duì)于所有需要訪問(wèn)JNDI管理的服務(wù)對(duì)象的客戶端而言,都需要進(jìn)行定位工作。在需要查找服務(wù)的客戶端中,會(huì)導(dǎo)致不必要的代碼重復(fù)現(xiàn)象。同時(shí),創(chuàng)建最初JNDI環(huán)境和在EJB本地對(duì)象上執(zhí)行查找都會(huì)占用大量的資源。如果多個(gè)客戶端反復(fù)地請(qǐng)求相同的bean本地對(duì)象,這種重復(fù)現(xiàn)象會(huì)嚴(yán)重影響應(yīng)用程序性能。

我們使用服務(wù)定位器對(duì)象來(lái)抽取所有的JNDI應(yīng)用,并且隱蔽最初環(huán)境創(chuàng)建、EJB本地對(duì)象查找和EJB對(duì)象重創(chuàng)建的復(fù)雜性。多個(gè)客戶端可以重新使用服務(wù)定位器對(duì)象來(lái)降低代碼的復(fù)雜性,提供單控制點(diǎn),并且通過(guò)提供緩沖機(jī)制來(lái)提高性能。

該模式降低了來(lái)自于客戶端依賴性的客戶端復(fù)雜性,并且需要執(zhí)行查找和創(chuàng)建過(guò)程,這些都是非常消耗資源的。為了消除這些問(wèn)題,該模式提供了把所有依賴性和網(wǎng)絡(luò)細(xì)節(jié)抽取到服務(wù)定位器的一種機(jī)制。它的位置如圖11中ServiceLocator所示。








圖11 服務(wù)定位器

功能代碼如下所示:

public class ServiceLocator { private static ServiceLocator me; InitialContext context = null; /** * 初始化上下文 */ public ServiceLocator() { try { context = new InitialContext(); } catch (NamingException e) { e.printStackTrace(); } } public class Services { //為EJB設(shè)定請(qǐng)求序號(hào) final public static int CUSTOMERS=0; final public static int PARTNERS=1; final public static int ADMINISTRATORS=2; final public static int PERMITS=3; final public static int PAPERBROKER=4; final public static int CHECK=5; } final static Class CUSTOMERS_CLASS=CustomersHome.class; final static String CUSTOMERS_NAME="CustomersHome"; final static Class PARTNERS_CLASS=PartnersHome.class; final static String PARTNERS_NAME="PartnersHome"; final static Class ADMINISTRATORS_CLASS=AdministratorsHome.class; final static String ADMINISTRATORS_NAME="AdministratorsHome"; final static Class PERMITS_CLASS=PermitsHome.class; final static String PERMITS_NAME="PermitsHome"; final static Class PAPERBROKER_CLASS=PaperBrokerHome.class; final static String PAPERBROKER_NAME="PaperBrokerHome"; final static Class CHECK_CLASS=CheckHome.class; final static String CHECK_NAME="CheckHome"; public static ServiceLocator getInstance() {//單線程處理以節(jié)省資源 if (me == null) me = new ServiceLocator(); return me; } static private Class getServiceClass(int service) { switch(service) { case Services.CUSTOMERS: return CUSTOMERS_CLASS; case Services.PARTNERS: return PARTNERS_CLASS; case Services.ADMINISTRATORS: return ADMINISTRATORS_CLASS; case Services.PERMITS: return PERMITS_CLASS; case Services.PAPERBROKER: return PAPERBROKER_CLASS; case Services.CHECK: return CHECK_CLASS; } return null; } static private String getServiceName(int service) { switch(service) { case Services.CUSTOMERS: return CUSTOMERS_NAME; case Services.PARTNERS: return PARTNERS_NAME; case Services.ADMINISTRATORS: return ADMINISTRATORS_NAME; case Services.PERMITS: return PERMITS_NAME; case Services.PAPERBROKER: return PAPERBROKER_NAME; case Services.CHECK: return CHECK_NAME; } return null; } /** * 返回EJB本地接口 */ public EJBHome getHome(int s) { EJBHome home = null; try { Object objref = context.lookup(getServiceName(s)); home = (EJBHome) PortableRemoteObject.narrow(objref, getServiceClass(s)); } catch (NamingException e) { e.printStackTrace(); } return home; }}缺點(diǎn):如果增加新的EJB,需要修改服務(wù)定位器的代碼。

以上這些模式都是可以通用的,在實(shí)際應(yīng)用中運(yùn)用這些模式,不僅加快了開(kāi)發(fā)進(jìn)度,而且開(kāi)發(fā)人員各司其職,避免了代碼的混亂,取得了比較好的效果。

三、總結(jié)

本文記述了根據(jù)J2EE模式和MVC開(kāi)發(fā)模型,利用IBM公司的WebSphere應(yīng)用服務(wù)器來(lái)組織建設(shè)網(wǎng)站的心得和體會(huì)。大家的項(xiàng)目類型也許會(huì)有不同,但開(kāi)發(fā)的模式總會(huì)有相通之處。善于根據(jù)實(shí)際情況選擇開(kāi)發(fā)模式,可以提高開(kāi)發(fā)效率和代碼質(zhì)量,但也不要一味死抱著模式不放,量體裁衣才能游刃有余。

最后:

最近有一些小伙伴粉絲讓我?guī)兔φ乙恍?面試題 資料。為幫助開(kāi)發(fā)者們提升面試技能、有機(jī)會(huì)入職BATJ等大廠公司,于是我翻遍了收藏的 5T 資料后特別制作了一個(gè)專輯一次整體放出。

說(shuō)明一下:所有的面試題目都不是一成不變的,特別是像一線大廠,下面的面試題只是給大家一個(gè)借鑒作用,最主要的是給自己增加知識(shí)的儲(chǔ)備,有備無(wú)患。大致內(nèi)容包括了: 各類大小廠面經(jīng)真題、Java 集合、JVM、多線程、并發(fā)編程、設(shè)計(jì)模式、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、spring面試題、spring cloud面試題、spring boot面試題、spring教程 筆記、spring boot教程筆記、最新阿里巴巴開(kāi)發(fā)手冊(cè)(63頁(yè)P(yáng)DF總結(jié))、2022年Java面試手冊(cè)一共整理了1184頁(yè)P(yáng)DF文檔。

如需獲取——點(diǎn)贊關(guān)注后私信(555)即可




感謝大家閱讀,在此表示感激不盡。文章持續(xù)更新中…

關(guān)鍵詞:利用,模式

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉