使用NetBeans快速開發Web Application(一)在Java EE 5裡包含了一個新的Web架構,Java Server faces,簡稱JSF。JSF的核心是在Web開發中引入了類似於Swing/AWT的組件結構,所有我們在瀏覽器裡看到的HTML控制項在伺服器端都有一個Java對象與其對應。由於Web應用中,用戶端(瀏覽器)和伺服器端(應用伺服器)分處在不同的運行環境中,用戶端的輸入值(如:inputText)和事件(如:點擊button)不能象Swing/AWT一樣直接在記憶體中傳輸,只能通過HTML表單的傳送來和伺服器互動,也就形成了傳統的request/reponse模式。JSF從某種意義上可以說是顛覆了這種模式,由於伺服器端組件的引入,我們在開發過程中可以忽略伺服器和用戶端不同運行環境的問題,假裝我們的Web程式是運行在同一台機器上,可以象Swing/AWT一樣方便地從組件取值並進行事件響應的處理。至於使用者介面是如何轉化成HTML,HTML又是如何轉化為Java組件則由JSF架構來完成,多數情況下我們都不用知道。NetBeans Visual Web Pack(簡稱NVWP)是基於JSF技術的一個工具,就象它的名字暗示的一樣,你可以用它來進行映像化的Web程式開發,就像以拖拽的形式開發Swing/AWT程式一樣,NVWP還對JSF進行了簡化,提供了DataProvider方便地把組件和資料聯絡在一起,還提供了圖形化介面以方便地提取資料和定義頁面流程。本文將引導你開發一個網路程式,以少量的編程,快速地開發一個功能齊全的網路程式來顯示資料庫資料。
下載安裝NetBeans 5.5和Sun Java Application Server 9(SJAS9) 1.下載並安裝NetBeans5.5,你可選擇單獨下載NetBeans或者是下載NetBeans和SJAS9的bundle。網址http://www.netbeans.info/downloads/index.php 2.下載並安裝NetBeans Visual Web Pack。網址http://www.netbeans.info/downloads/index.php?rs=11&p=9 3.若你選擇單獨下載SJAS9,可到以下網址下載:http://www.sun.com/software/products/appsrvr_pe/index.xml
TravelAgent Web應用程式開發在這個例子中我們要開發一個公司職員旅行清單的程式,一共有兩個頁面,第一頁可通過一個下拉式功能表來選擇公司職員,同時顯示這個職員所有的旅程,當一個旅程被選中就會切換到第二頁顯示和這個旅程相關的航班資訊和旅館資訊。程式所用的資料都存於資料庫,為了開發方便,NetBeans整合了一個JavaDB(Sun版的Apache Derby),NVWP安裝時會建立一個travel資料庫,我們的例子就使用這個資料庫的資料。如果用傳統的編程方式,雖然這個程式很簡單也會至少花掉一個資深工程師大約半天的時間,但使用NVWP,所有時間加起來不會超過半小時。好!廢話少說,開發開始。
1
啟動NetBeans
2
建立一個新項目: “
檔案” -> “
建立項目” 2.1 在對話方塊中選擇,點擊”
下一步” 2.2 作如下修改後,點擊“
完成” 2.3 NetBeans建立“TravelAgent“項目,並開啟Page1.jsp和相關的”
組件面板“。在NVWP裡Page1.jsp就是Web應用的第一頁,NVWP已在web.xml做了相應的改變。同時NVWP建立了三個JSF受管Bean(受管Bean定義詳見JSF資料)對應於Request, Session和Application,用於傳送相應scope的變數。 2.4 在螢幕右方的“
組件面板“裡定義了一系列的JSF組件,在開發時可象Swing組件一樣以拖拽的形式放到使用者介面裡。其中”
Standard“目錄下定義的是JSF specification裡規定的標準組件,”
Basic”目錄下是NetBeans提供的增強型的組件,我們會用”
Basic“目錄下的組件來開發這個程式。 2.5 從“
Basic“目錄裡拖一個”Image“組件放在介面左上端。 2.6 右點“<Image>“,在快顯視窗選”Set Image“,選擇提供的”header.jpg“(本文開頭就是啦) 2.7 調整好圖形後,拖入一個“
Label“組件,並把Label顯示文字改成Employee: 2.8 接著拖入一個“
Drop down list“和一個”
Table“組件到介面中 2.9 右擊“Item1“,在快顯功能表中選”Auto-submit on Change“。這一步的目的是使用者在下拉式功能表中選擇另一僱員時自動重新整理介面。 2.10 接下來我們要做的是把介面中的下拉式功能表組件和表組件跟資料聯絡起來。我們的資料來自於NetBeans整合的資料庫。 2.11 切換到“
運行環境“。右擊串連”Travel“資料庫,資料庫密碼和使用者名稱相同。 2.12 開啟資料庫表,把”Person”表拖到下拉式功能表組件上,把”Trip“拖到表組件上。注意下拉式功能表不再顯示”Item1“而是顯示”abc“,說明它已和資料來源串連。表組件也有改變,現在顯示的是”Trip“表的內容。 2.13 表組件要顯示的是下拉式功能表中所選的僱員的旅行清單,所以表組件需要知道下拉式功能表中選中的僱員,這個由後面的簡單編程完成,同時表組件要根據選中的僱員來提取旅行資訊。在前一步我們串連資料來源時,NVWP在SessionBean1(也就是Session)放入了一個tripRowSet對象,這個對象用於從資料庫中提取資料然後傳給表組件,我們需要給它加一點約束條件。NVWP提供了一個映像化的SQL編輯器可協助我們做這件事。在“
Outline“視窗雙擊”tripRowSet“,開啟SQL編輯器。在”PERSONID“一行加入Criteria:”=?“並斷行符號,。” WHERE TRAVEL.TRIP.PERSONID = ?“應被加到SQL語句中。 2.14 回到“Page1“的介面,接下來要做的是加入來源程式來響應下拉式功能表值改變時產生的事件。雙擊下拉式功能表,NetBeans切換到Page1的Java視窗,並把游標停在dropDown1_processValueChanged方法。 2.15 在dropDown1_processValueChange方法裡加入以下程式(拷貝以下程式即可)。若你得到出錯資訊,先不管它,我們還有兩個變數沒有定義。這段來源程式做的事很簡單,它先從下拉式功能表取得所選僱員的ID,然後把這個ID傳給SessionBean1和tripRowSet(參看我們在2.13裡定義的約束條件),最後更新一下tripDataProvider。tripDataProvider是給表組件提供資料的,它的更新使表組件顯示新的資料。
| public void dropDown1_processValueChange(ValueChangeEvent event) { try { Integer selectedPersonID = (Integer) dropDown1.getSelected(); getSessionBean1().setPersonID(selectedPersonID); getSessionBean1().getTripRowSet().setObject(1, selectedPersonID); tripDataProvider.refresh(); } catch (Exception e) { error("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID")); log("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID"), e); } } |
2.16 在來源程式裡往上翻,找到prerender方法,這個方法會在每次該頁面渲染(render)前被調用,用於執行頁面渲染前的預先處理。 2.17 在prerender方法裡敲入以下程式。這段程式首先查看是否有選中的僱員,若沒有(第一次訪問該頁)則從personDataProvider裡取出第一個值,並把這個值傳給tripRowSet,然後更新tripDataProvider,從而更新表組件的顯示。若Session裡已有選中的僱員(之前已訪問過該頁),則確保下拉式功能表顯示的是該僱員。你會得到出錯資訊,SessionBean1裡還需要定義兩個變數。
| public void prerender() { if (getSessionBean1().getPersonID() == null ) { try { personDataProvider.cursorFirst(); getSessionBean1().getTripRowSet().setObject(1, personDataProvider.getValue("PERSON.PERSONID")); tripDataProvider.refresh(); } catch (Exception e) { error("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID")); log("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID"), e); } } else { dropDown1.setSelected(getSessionBean1().getPersonID()); } } |
2.18 這一步我們要在SessionBean1裡加入兩個變數,2.15和2.17兩步裡出現的錯誤就是因為這兩個變數還沒有定義造成的。我們先加入這兩個變數的定義,再在下一步用重構把它們封裝起來。加入如下變數定義,注意別敲錯了。
| Integer tripID;Integer personID; |
2.19 重構:在原始碼編輯器裡點右鍵,選擇 “
重構” ᄄC> “
封裝欄位”;然後在對話方塊選擇和tripID和personID相關的方法;預覽修改後,點擊“
進行重構”,如下面幾幅圖所示。NetBeans會自動幫你加入getters和setters方法。 2.20 到這一步我們幾乎已完成一半了,右鍵“
TravelAgent”項目,選擇“
Run Project”。試著改變下拉式功能表,你會看到表單會顯示相應僱員的旅行清單。若你沒有看到更新,可能是你錯過了2.9那一步。接下去我們要對錶單做三個修改: 2.21 表單的抬頭直接來自資料庫,需要改成有意義的名稱,比如:DEPCITY改成 From 2.22 隱藏一些使用者不想看到的列,比如:TRIPID和LASTUPDATED 2.23 把TRIPID列改成button或者是hyperlink,使用者可以點擊進入下一頁。 2.24 在“
Design”視窗,右鍵表組件,選擇“
Table Layout” 2.25 在快顯視窗,移除“PERSONID”,”TRIPTYPEID”和“LASTUPDATED”。 2.26 然後把TRIPID的“Header Text”改成“Trip ID”, 並把“Component Type”改成“Button” 2.27 把“DEPDATE”改成“Departure Date”, “DEPCITY”改成“From”, “DESTCITY”改成“To”, 然後點擊“
確定” 2.28 表單介面變成如下: 2.29 當使用者點擊“TripID” button,我們需要把所選的“TripID”設給SessionBean1.tripID變數,以便下一頁使用。雙擊“123”Button,在顯示切換到原始碼編輯器後,在button1_action方法裡加入以下程式:
| public String button1_action() { Integer tripID = (Integer) button1.getValue(); getSessionBean1().setTripID(tripID); return null; } |
2.30 到這,第一頁的開發完成,運行項目,你已經可以看見一個運行完好的應用程式 3 現在我們來做第二頁,這一頁顯示的是使用者在上一頁所選旅行的細節,象旅館資訊和航班資訊。右鍵”
TravelAgent”項目,選擇“建立” ->“
Page…”,NetBeans會產生Page2.jsp並將其開啟。 3.1 旅館資訊和航班資訊來自資料庫中的Hotel和Flight表 3.2 作為練習,請用在步驟2中學到的方法做以下工作 3.2.1 用拖拽的方式產生所示介面,別忘了頁面底端有一個Button。 3.2.2 把表單和相應的資料庫連起來, 參看步驟2.12。 3.2.3 給hotelRowSet和flightRowSet中加入tripID的約束條件,參看步驟2.13 3.2.4 修改表單的抬頭。參看步驟2.27 3.3 在prerender()方法裡加入以下code,這些code做的事情和步驟2.17裡做的相同。
| public void prerender() { try { Integer tripID = getSessionBean1().getTripID(); getSessionBean1().getFlightRowSet().setObject(1, tripID); flightDataProvider.refresh(); getSessionBean1().getHotelRowSet().setObject(1, tripID); hotelDataProvider.refresh(); } catch (DataProviderException ex) { ex.printStackTrace(); } catch (SQLException ex) { ex.printStackTrace(); } } |
3.4 最後要做的就是定義流程,怎麼從第一頁到第二頁,又怎麼從第二頁回到第一頁。NVWP為此提供了一個映像化的介面可以讓你很方便定義流程。回到“Design”視窗,然後在空白處點右鍵,選擇“
Page Navigation”。 3.5 在跳出的Navigation視窗,Page1中的button拖到Page2即可,同理將page2中的button拖到Page1. 3.6 恭喜,你已完成了一個網路應用程式的開發。運行程式,可看到以下介面: 4 常見問題: 4.1 問:資料庫的資料是直接拖過來的,我怎麼才知道用的是什麼資料來源? 答:在我們拖資料來源的時候,NVWP自動化佈建了資料來源,資料來源的定義可在“伺服器資源”找到。: 4.2 問:在Page1裡面,下拉式功能表顯示的是僱員名稱,可值是僱員ID,這是怎麼回事? 答:下拉式功能表的顯示和值是可以設的。右鍵Page1裡的下拉式功能表,選擇“Bind To Data”,可得到如下的快顯視窗,這裡你可選擇下拉式功能表的顯示和值 4.3 問:下拉式功能表的值只能對應資料表格中的一列嗎? 如果名字在資料表格中不是一列而被分成姓,名兩列怎麼辦?答: 這個問題可以解決,但不能通過映像化的方式,要手動修改給下拉式功能表提供資料的personRowSet的SQL語句。開啟personRowSet。手動將SQL語句改成如下,然後再通過4.2介紹的方法重新選擇顯示和值。
| SELECT ALL TRAVEL.PERSON.PERSONID, TRAVEL.PERSON.NAME||TRAVEL.PERSON.JOBTITLE AS displayFROM TRAVEL.PERSON |
4.4 問:DataProvider只能串連資料庫表嗎? 答:用DataProvider串連Web服務,EJB在NVWP的前身Sun Java Studio Creator裡是可以的,目前我還沒有在NVWP看到這些功能。待這些功能加入到NVWP後我會另寫文章詳述。
本文轉自http://developers.sun.com.cn/blog/sunblade/entry/20070522