top
Loading...
Bean和Servlet的企業應用(1)
p>J2EE是一個企業應用程序的開發平臺,包括了對EJB、Servlet、JavaServer Page、JNDI、XML等的支持。在這個平臺上可以開發瘦客戶端的多層體系結構的企業應用程序。

Enterprise JavaBean技術是J2EE的主要基礎。EJB技術對在分布式的計算環境中執行應用邏輯提供了一個可伸縮的框架結構。J2EE通過將EJB組件結構和其它的企業技術相結合,解決了在Java平臺上進行開發和配置服務端應用程序的無縫結合。

要使用J2EE開發您的企業應用,您必須要在您的機器上安裝一個Web服務器,還要支持XML。為了在瀏覽器中運行Java 2的API,還要給您的瀏覽器安裝一個支持Java2的插件。

下面就介紹怎樣用J2EE SDK寫一個包括了HTML頁面,Servlet和Session Bean的一個簡單的瘦客戶端的多層體系結構的企業應用程序。聽起來是不是心動了呢?下面就開始吧。還要提醒一點的就是:在編程的時候,適當的增加catch子句是一個很好編程風格。如果例子代碼拋出了一個正確的異常,代碼就被 try/catch這樣的程序結構包圍。Catch子句應該中應該加入處理異常的代碼,千萬不要留成空白。至少,應該加入語句:e.printStackTrace()來在控制臺顯示異常信息。

J2EE SDK是一個J2EE平臺上用于演示、教育等用途的非商業的東東。可以從javasoft的網站上免費下載。很適合用來學習。如果你沒有出國權限,還可以從國內各高校的FTP服務器上去下載,速度比較快,但可能版本不是最新的。

瘦客戶端的多層體系結構的應用程序的例子:

本例子通過一個HTML頁面的輸入來調用一個Servlet,Servlet再用Java的名字目錄服務接口(JNDI)APIs來尋找一個會話Session Bean,用這個Session Bean來執行一個計算。當Servlet得到了計算的結果的之后,Servlet把計算結果返回給HTML頁面的用戶。

之所以說這是一個瘦客戶端的應用程序,是因為Servlet本身并沒有執行任何的應用邏輯。這個簡單的計算是由一個Session Bean在J2EE的應用服務器上執行的。客戶沒有參與過程的任何操作,所有的計算都是由Session Bean完成的。

所謂的多層體系結果實際上是由三或者四層組成的。我們的例子實際上是四層的一個結構。三層的體系結構是在標準的兩層的客戶/服務器結構基礎上,將一個多線程的應用服務器加到了非瀏覽器的客戶端和后臺數據庫之間。而四層的體系結構是通過Servlet和JavaServer Pages技術將客戶端的應用程序由瀏覽器和HTML頁面來取代 飧隼游頤竊菔敝揮悶渲械娜悖諳亂桓隼又小N頤竊偃シ夢適菘狻U庋屠┱溝剿牟懔恕T僖院螅頤腔嶸婕暗絁avaServer Pages技術和XML技術。

2EE軟件的安裝:

為了使我們的例子能夠運行起來,首先要下載一個Java2 SDK Enterprise Edition(J2EE)的1.2.1的版本和一個J2SE(Java 2 Standard Edition)的1.2以上的版本。在Windows 2000系統中,假設我們把J2EE和J2SE都裝到了C:J2EE目錄下。安裝詳細目錄如下:

J2EE:C:J2EEj2sdkee1.2.1

J2SE:C:J2EEjdk1.2.2


Path和ClassPath的設置:

下載的東西包括了J2EE的應用服務器、Cloudscape數據庫、使用了加密套接字協議層的Web服務器、開發和配置的工具、企業級的Java APIs。其Path和ClassPath的設置如下:

Path的設置:在Windows系統中,需要把Path的目錄包含下面兩個目錄:

C:J2EEj2sdkee1.2.1in

C:J2EEjdk1.2.2in

Classpath的設置:在Windows系統中,需要把Classpath參數包含下面的文件:

C:J2EEj2sdkee.1.2.1libj2ee.jar

另外,還要配置環境變量:

J2EE_HOME=C:J2EEj2sdkee1.2.1

JAVA_HOME=C:J2EEjdk1.2.2

這樣,就可以執行C:J2EEj2sdkee1.2.1in目錄下面的批處理命令了。仔細看看里面的批處理,你會發現不少的東西的。

J2EE應用程序組件:

J2EE程序員編寫J2EE組件。J2EE組件是一個功能齊全的軟件單元。將其它的應用程序組件組裝到J2EE的應用程序和接口中。J2EE規范中定義如下的應用程序組件:


應用程序客戶組件


Enterprise JavaBean組件


Servlet和JavaServer Pages組件(也叫做Web組件)


Applet

在本例子中,我們創建了一個J2EE的應用程序和兩個J2EE的組件:一個Servlet和一個Session Bean。Servlet和HTML文件是捆綁在一個WAR(WEB Archive)文件中。Session Bean的類和接口捆綁到了一個JAR文件中。然后再把WAR文件和JAR文件加到J2EE的應用程序,捆綁到一個EAR(Enterprise Archive)文件中。并驗證測試產品環境的配置。

在這所有的步驟中。實際上執行了很多的不用的角色的功能。編寫Session Bean和Servlet是開發工作。而創建一個J2EE的應用程序,將J2EE組件組裝到應用程序中是應用程序的組裝工作。實際上,這些工作可以在不同的地方由不用的人員來做。

創建一個HTML頁面:

這個頁面名字為bonus.html。HTML代碼如下:

代碼中,讓人感興趣的是用別名來調用BonusServlet.class。因為在后面提到的應用程序的組裝的時候,將它映射到了這個別名BonusServlet上

$#@60;HTML$#@62;

$#@60;BODY BGCOLOR = "WHITE"$#@62;

$#@60;BLOCKQUOTE$#@62;

$#@60;H3$#@62;Bonus Calculation$#@60;/H3$#@62;

$#@60;FORM METHOD="GET" ACTION="BonusAlias"$#@62;

$#@60;P$#@62;

Enter social security Number:

$#@60;P$#@62;

$#@60;INPUT TYPE="TEXT" NAME="SOCSEC"$#@62;$#@60;/INPUT$#@62;

$#@60;P$#@62;

Enter Multiplier:

$#@60;P$#@62;

$#@60;INPUT TYPE="TEXT" NAME="MULTIPLIER"$#@62;$#@60;/INPUT$#@62;

$#@60;P$#@62;

$#@60;INPUT TYPE="SUBMIT" VALUE="Submit"$#@62;

$#@60;INPUT TYPE="RESET"$#@62;

$#@60;/FORM$#@62;

$#@60;/BLOCKQUOTE$#@62;

$#@60;/BODY$#@62;

$#@60;/HTML$#@62;

這個HTML文件有兩個數據域,用戶可以輸入社會保險號和一個乘數。當用戶單擊了Submit按紐。BonusServlet就得到了終端用戶的數據。然后尋找Session Bean。將用戶數據傳遞給Session Bean。Session Bean計算出獎金,把結果返回給Servlet。Servlet再通過另一個HTML頁面將獎金結果返回給用戶。

創建Servlet:

例子假定BonusServlet.java文件是在C:J2EEClient-Code目錄下面。在運行的時候,Servlet代碼執行如下操作:


獲得用戶數據


查找Session Bean


將用戶數據傳遞給Session Bean


在得到Session Bean的返回結果以后,創建一個HTML頁面將結果返回給客戶。


Servlet代碼如下:

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import javax.naming.*;

import javax.rmi.PortableRemoteObject;

import Beans.*;

public class BonusServlet extends HttpServlet {

CalcHome homecalc;

public void init(ServletConfig config)

throws ServletException{

//Look up home interface

try{

InitialContext ctx = new InitialContext();

Object objref = ctx.lookup("calcs");

homecalc =

(CalcHome)PortableRemoteObject.narrow(

objref,

CalcHome.class);

} catch (Exception NamingException) {

NamingException.printStackTrace();

}

}

public void doGet (HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

String socsec = null;

int multiplier = 0;

double calc = 0.0;

PrintWriter out;

response.setContentType("text/html");

String title = "EJB Example";

out = response.getWriter();

out.println("$#@60;HTML$#@62;$#@60;HEAD$#@62;$#@60;TITLE$#@62;");

out.println(title);

out.println("$#@60;/TITLE$#@62;$#@60;/HEAD$#@62;$#@60;BODY$#@62;");

try{

Calc theCalculation;

//Get Multiplier and Social Security Information

String strMult =

request.getParameter("MULTIPLIER");

Integer integerMult = new Integer(strMult);

multiplier = integerMult.intValue();

socsec = request.getParameter("SOCSEC");

//Calculate bonus.10 AUGUST 28, 2000

double bonus = 100.00;

theCalculation = homecalc.create();

calc =

theCalculation.calcBonus(multiplier, bonus);

} catch(Exception CreateException){

CreateException.printStackTrace();

}

//Display Data

out.println("$#@60;H1$#@62;Bonus Calculation$#@60;/H1$#@62;");

out.println("$#@60;P$#@62;Soc Sec: " + socsec + "$#@60;P$#@62;");

out.println("$#@60;P$#@62;Multiplier: " +

multiplier + "$#@60;P$#@62;");

out.println("$#@60;P$#@62;Bonus Amount: " + calc + "$#@60;P$#@62;");

out.println("$#@60;/BODY$#@62;$#@60;/HTML$#@62;");

out.close();

}

public void destroy() {

System.out.println("Destroy");

}

}


在import子句中,javax.servlet包括了Servlet Class的協議。Java.io是系統輸入輸出包。Javax.naming里面包含了Java名字目錄服務APIs。Javax.rmi是用來Session Bean的home接口和Remote對象的通信使用的。

在BonusServlet.init方法中,查找Session Bean的home接口。并且產生它的實例。方法使用了JNDI在組件的組裝中的指定的名字calcs。用它來得到home接口的reference。然后就把這個reference和home接口類傳遞給PortableRemoteObject.narrow方法。來保證把reference轉化為CalcHome類型。

DoGet()方法有兩個參數。一個是request對象,另一個是reponse對象。瀏覽器發送一個request對象給Servlet。而Servlet返回一個response對象給瀏覽器。方法訪問request對象里面的信息,可以發現是誰在發出的請求、請求的數據在什么表單里面、是哪個HTTP頭被發送。并使用reponse對象產生一個HTML頁面來響應瀏覽器的請求。

當方法處理請求的時候,如果產生輸入輸出錯誤,就拋出一個IOException異常。如果不能處理請求,就會拋出一個ServletException異常。為了計算獎金值,doGet()創建了一個home接口,調用它的calcBonus。

創建Session Bean:

Session Bean代表了與客戶的一個短暫的會話。如果服務或者客戶有一方崩潰了。數據就消失了。相反,Entity Bean代表了數據庫中一段持久的數據。如果服務或者客戶又一方崩潰了,底層的服務保證數據能被保存下來。

因為這個Enterprise Bean只是應BonusServlet的請求,執行了一個簡單的計算。如果發生崩潰,可以重新初始化計算。這樣,我們在本例子中就選擇Session Bean來實現這個計算。

在組裝配置好以后,Servlet組件和Session Bean組件如何在一個J2EE應用程序中協同工作。容器是Session Bean和支持Session Bean的底層平臺之間的接口。容器是在配置期間產生的。

本例子假定CalcBean.java、Calc.java和CalcHome.java文件都放在C:J2EEBeans目錄下面。CalcHome.java文件前面的Package名字 Beans和目錄Beans的名字應該是一樣的。當這些文件被編譯的時候,是從Beans目錄中編譯,其名字是包的名字后面加一個斜線在加上類或者接口的名字。


CalcHome.java文件:

package Beans;

import java.rmi.RemoteException;

import javax.ejb.CreateException;

import javax.ejb.EJBHome;

public interface CalcHome extends EJBHome {

Calc create() throws CreateException, RemoteException;

}

BonusServlet并不直接同Session Bean通信。而是通過產生一個CalcHome的實例。這個Home接口擴展了EJBHome接口。有一個Create()方法,用來在容器中產生一個Session Bean。如果無法產生Session Bean,將會拋出一個CreateException異常。如果不能與Session Bean的遠程方法通信,就會拋出一個RemoteException異常。


Calc.java文件:

package Beans;

import javax.ejb.EJBObject;

import java.rmi.RemoteException;

public interface Calc extends EJBObject {

public double calcBonus(int multiplier,

double bonus)

throws RemoteException;

}

產生一個Home接口以后,J2EE應用程序就創建一個Remote接口和一個Session Bean。Remote接口擴展了EJBObject接口。并且聲明了一個calcBonus()方法來計算獎金值。方法需要拋出javax.rmi.RemoteException異常。方法的實現在CalcBean類里面。


CalcBean.java文件:

package Beans;

import java.rmi.RemoteException;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

public class CalcBean implements SessionBean {

public double calcBonus(int multiplier,

double bonus) {

double calc = (multiplier*bonus);

return calc;

}

public void ejbCreate() { }

public void setSessionContext(

SessionContext ctx) { }

public void ejbRemove() { }

public void ejbActivate() { }

public void ejbPassivate() { }

public void ejbLoad() { }

public void ejbStore() { }

}

本Session Bean類實現了SessionBean接口,提供了CalcBonus()方法的行為。在BonusServlet調用CalcHome的Create()方法以后,依次調用setSessionContext()方法和ejbCreate()方法。

這些空的方法是從SessionBean中來的。由容器負責調用。除非在Bean的創建或者刪除里面,你需要附加一些你自己的操作。否者,你并不需要提供這些方法的行為。

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗