<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    談笑有鴻儒,往來無白丁

    在恰當的時間、地點以恰當的方式表達給恰當的人...  閱讀的時候請注意分類,佛曰我日里面是談笑文章,其他是各個分類的文章,積極的熱情投入到寫博的隊伍中來,支持blogjava做大做強!向dudu站長致敬>> > 我的微博敬請收聽

    使用 Oracle JDeveloper 構建您的第一個 GWT Web 應用程序

    到目前為止,您已經了解了 GWT 的工作方式;現在,讓我們編碼示例 Web 應用程序。

    示例應用程序是一個工作列表管理器。其特性十分簡單:創建、編輯、刪除工作列表并對其進行優先級排列。我們選擇了該示例是因為它很容易理解,然而其實施涵蓋了大量 GWT 的特性。

    下面是最終應用程序的屏幕快照:

    圖 1

    第 1 步:安裝 GWT

    從 Google 的 Web 站點 http://code.google.com/webtoolkit/ 下載 GWT。在寫本文時,GWT 推出的是 Windows 和 Linux 版本。GWT 是特定于平臺的,因為其托管模式在 Firefox 的修改版本中工作,該版本本身依賴于平臺。(我們可以在 Apple 計算機上成功地使用 GWT 的 Linux 版本,但是托管模式不起作用。)

    GWT 下載形式是一個歸檔文件,您必須使用 Linux 上的 tar -xvf 命令或者 Windows 上的解壓縮工具進行解壓縮。這就是您安裝該工具包需要做的所有工作。

    第 2 步:運行 applicationCreator 腳本

    打開命令行,轉至 GWT 的安裝目錄。該目錄包含 applicationCreator 腳本,我們將使用該腳本啟動我們的應用程序。由于我們希望應用程序存儲在 Oracle Technology Network 目錄中,因此我們將“-out otn”作為參數添加到腳本中。在 Linux 上,鍵入:

    ./applicationCreator -out otn otn.todo.client.TodoApp

    圖 2

    在 Windows 上,使用:

    applicationCreator -out otn otn.todo.client.TodoApp
    該腳本生成基本的項目結構 — 請求的應用程序類中的示例“Hello word”代碼以及兩個腳本:TodoApp-shell(用于在托管模式下運行應用程序)和 TodoApp-compile(用于打包應用程序以便在 Web 模式下使用)。

    第 3 步:在 JDeveloper 中打開項目

    啟動 JDeveloper 并創建一個新的 Web 項目:

    圖 3

    單擊 Next 按鈕。JDeveloper 將詢問新項目的位置。使用應用程序的名稱作為 Project Name,選擇應用程序根目錄(如步驟 2 的定義)作為 Directory Name

    圖 4

    單擊 Next 按鈕,并驗證您的應用程序是 J2EE 1.4 應用程序:

    圖 5

    單擊 Next 按鈕,并選擇您的項目 Web 屬性:Document Root 是當前項目的 www 目錄,J2EE Web Application Name 和 J2EE Context Root 都是項目名稱:

    圖 6

    這將創建 JDeveloper 項目,但是將出現某些編譯錯誤,因為 GWT 的庫未包含在項目類路徑中。在項目屬性中,選擇左側端樹的 Libraries 節點,并添加 gwt-user.jar 庫:

    圖 7

    您的項目現在應該可以編譯,看起來與以下內容相似:

    圖 8

    編寫客戶端代碼

    上面的 applicationCreator 腳本創建了一個基本的“Hello world”應用程序,可在 otn.todo.client 程序包中使用。下面是其主要方法:

    public void onModuleLoad() {
    final Button button = new Button("Click me");
    final Label label = new Label();

    button.addClickListener(new ClickListener() {
    public void onClick(Widget sender) {
    if (label.getText().equals(""))
    label.setText("Hello World!");
    else
    label.setText("");
    }
    });

    RootPanel.get("slot1").add(button);
    RootPanel.get("slot2").add(label);
    }
    }
    該方法將創建一個按鈕“Click Me”。單擊該按鈕后,將顯示“Hello World”。

    該方法分為三部分:

    1. 創建 Button 和 Label 小部件
    2. 創建 ClickListener 對象。該代碼與您用 Swing 編寫的內容很接近;如果您具有桌面 Java 背景則更容易理解。
    3. 在 HTML 頁上顯示小部件:slot1 和 slot2 都是該頁上的 HTML 元素
    用作框架的 HTML 頁位于 src/otn/todo/public 目錄中。它將兩個 HTML 元素(slot1 和 slot2)定義為表單元格。

    在托管模式下運行和調試


    現在您已經創建了應用程序并且已經看到其生成的內容,結下來讓我們來執行它。

    您可以通過從命令行使用 TodoApp-shell 腳本輕松地運行該項目。雖然這是啟動應用程序的很好途徑,但是您可能更喜歡直接從 JDeveloper 內啟動應用程序。為此,單擊 Run 菜單,選擇 Choose Active Run Configuration > Manage Run Configurations。編輯默認的運行配置并使用以下命令:

    • 對于 Default Run Target:使用 com.google.gwt.dev.GWTShell,它在特定于平臺的 GWT jar 內。在 Linux 上,它類似以下內容:
      path.to.your.gwt.installation.directory/gwt-devlinux.jar!/com/google/gwt/dev/GWTShell.class
      在 Windows 上,它類似以下內容:
      path.to.your.gwt.installation.directory/gwt-dev-windows.jar!/com/google/gwt/dev/GWTShell.class
    • 對于 Program Arguments,使用:
      -out path.to.your.gwt.installation.directory/otn/www otn.todo.TodoApp/TodoApp.html
    • 對于 Run Directory,使用
      path.to.your.gwt.installation.directory/otn
    最終結果類似以下內容:

    圖 9

    要運行您的應用程序,您必須向其類路徑中再添加兩個庫:GWT 特定于平臺的 jar 和應用程序的 src 目錄:

    圖 10

    您現在應能夠從 JDeveloper 運行應用程序了。

    這是一個很復雜的設置,但是令人欣慰的是,您可以重新使用它對應用程序進行調試。使用 Debug 按鈕而不是 Run 按鈕。然后,您可以象平常一樣使用調試器 — 設置斷點、逐步執行代碼等:

    圖 11

    關于該特性給人印象很深的是,您可以通過標準的 JDeveloper 調試器調試用 Java 編寫的客戶端代碼。

    擴展您的 GWT Web 應用程序

    現在您已經創建了一個簡單的 GWT Web 應用程序,讓我們通過兩個最常用的 GWT 特性對其進行擴展:RPC 機制(該機制允許應用程序調用服務器端代碼)和 History 對象(通過該對象,用戶可精確處理瀏覽器的 Back 按鈕)。

    使用 RPC 進行客戶端和服務器之間的數據交換

    到目前為止,您只創建了應用程序的客戶端代碼:使用 GWT 編譯器,您已經生成了大量 HTML 和 JavaScript 文件,它們將在最終用戶的瀏覽器中運行。但是,如果該應用程序不能與服務器通信就沒有什么用處了。

    使用 GWT,客戶端/服務器通信就是對 servlet 進行編碼并使其與應用程序通信。下面是您要做的工作。

    創建一個定義您的服務的接口。該接口必須擴展 Google 的 com.google.gwt.user.client.rpc.RemoteService 接口,并可以放到客戶端程序包(本例為 otn.todo.client)中。

    然后,對接口進行編碼以便允許您在服務器上讀取和寫入工作列表:

    package otn.todo.client;
    import java.util.List;
    import com.google.gwt.user.client.rpc.RemoteService;
    public interface TodoListBackupService extends RemoteService {
    /**
    * Save the to-do list on the server.
    */
    void saveTodoList(List todoList);
    /**
    * Get the to-do list on the server.
    */
    List getTodoList();
    }
    對 Servlet 進行編碼。在服務器端,您必須編碼出具有以下特征的類:
    1. 擴展 Google 的 com.google.gwt.user.server.rpc.RemoteServiceServlet 類(該類反過來會擴展 Java 的 javax.servlet.http.HttpServlet,有效使其成為 servlet)
    2. 實施步驟 1 中編寫的接口
    3. 位于服務器程序包(本例為 otn.todo.server)中
    package otn.todo.server;

    import java.util.ArrayList;
    import java.util.List;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;

    import otn.todo.client.Todo;
    import otn.todo.client.TodoListBackupService;

    import com.google.gwt.user.server.rpc.RemoteServiceServlet;

    public class TodoListBackupServiceImpl extends RemoteServiceServlet implements
    TodoListBackupService {

    private static final String TODOLIST_KEY = "TODOLIST_KEY";

    public void saveTodoList(List todoList) {
    HttpServletRequest request = this.getThreadLocalRequest();
    HttpSession session = request.getSession();
    session.setAttribute(TODOLIST_KEY, todoList);
    }

    public List getTodoList() {
    HttpServletRequest request = this.getThreadLocalRequest();
    HttpSession session = request.getSession();
    if (session.getAttribute(TODOLIST_KEY) == null) {
    List todoList = new ArrayList();
    Todo todo = new Todo("Hello from the server");
    todoList.add(todo);
    return todoList;
    } else {
    return (List) session.getAttribute(TODOLIST_KEY);
    }
    }
    }
    該 servlet 在用戶的 HttpSession 中只存儲工作列表;這當然是保存數據的基本方法。在一般的應用程序中,您可以使用 JNDI 訪問 EJB,或者使用任何經典模式從 servlet 訪問業務服務。

    最后,您必須在 servlet 容器內配置該 servlet。如果您使用的是 GWT shell,您可以在 *.gwt.xml 配置文件中進行配置,本例中該配置文件為 TodoApp.gwt.xml:

    <module>
    <!-- Inherit the core Web Toolkit stuff. -->
    <inherits name='com.google.gwt.user.User'/>
    <!-- Specify the app entry point class. -->
    <entry-point class='otn.todo.client.TodoApp'/>
    <servlet path="/todoListBackupService" class="otn.todo.server.TodoListBackupServiceImpl"/>
    </module>
    如果您希望在其他應用服務器(如 OC4J)中對其進行配置,只需將平常的 XML 配置添加到 WEB-INF/web.xml 文件中即可:
    <servlet>
    <servlet-name>TodoListBackupService</servlet-name>
    <servlet-class>otn.todo.server.TodoListBackupServiceImpl</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>TodoListBackupService</servlet-name>
    <url-pattern>/todoListBackupService</url-pattern>
    </servlet-mapping>
    添加一些粘合劑。我們需要的粘合劑是 Async 類,它必須遵循幾個規則:
    • 位于客戶端程序包(otn.todo.client)中。
    • 其名稱與步驟 1 中描述的接口的名稱相同,最后面添加 Async。
    • 其方法與步驟 1 中描述的接口的方法相同,但是它們都回調一個附加參數 com.google.gwt.user.client.rpc.AsyncCallback。
    package otn.todo.client;

    import java.util.List;


      import com.google.gwt.user.client.rpc.AsyncCallback;

      public interface TodoListBackupServiceAsync {

      /**
      * Save the to-do list on the server.
      */
      void saveTodoList(List todoList, AsyncCallback callback);

      /**
      * Get the to-do list on the server.
      */
      void getTodoList(AsyncCallback callback);
      }
      在應用程序內使用該類。要從客戶端應用程序內訪問服務器端代碼,使用 com.google.gwt.core.client.GWT 類,該類可以創建一個很特殊的對象:
      TodoListBackupServiceAsync todoListBackupService = (TodoListBackupServiceAsync) GWT.create(TodoListBackupService.class);
      這將在運行時創建一個實施兩個接口的類:
      • 我們剛剛在步驟 3 中進行編碼的 Async 接口
      • Google 的 com.google.gwt.user.client.rpc.ServiceDefTarget 接口
      第二個接口用于配置類以便它可以指向步驟 2 中定義的 servlet:
      ServiceDefTarget endpoint = (ServiceDefTarget) todoListBackupService; endpoint.setServiceEntryPoint("/todoListBackupService");
      現在您已經將該對象配置為可訪問服務器端服務,讓我們來訪問服務。如您在步驟 3 中所見,Async 接口允許您通過添加 AsyncCallback 回調參數訪問在服務中定義的所有方法。該參數用于定義應用程序的行為,具體取決于服務器端調用的成功或失敗:
       AsyncCallback callback = new AsyncCallback() {
      public void onSuccess(Object result) {
      printTodoList();
      }

      public void onFailure(Throwable caught) {
      Window.alert("Warning : the to-do list could not be saved on the server. Maybe the server is down.");
      }
      };
      讓我們把它們全都放在一起。下面是訪問 TodoListBackupService 業務服務的兩個客戶端方法的完整代碼:一個用于在服務器端保存工作列表,另一個用于讀取該列表:
       /**
      * Update the to-do list with data from the server.
      */
      private void updateTodoListFromServer() {
      TodoListBackupServiceAsync todoListBackupService =
      (TodoListBackupServiceAsync)GWT.create(TodoListBackupService.class);

      ServiceDefTarget endpoint = (ServiceDefTarget)todoListBackupService;
      endpoint.setServiceEntryPoint("/todoListBackupService");

      AsyncCallback callback = new AsyncCallback() {
      public void onSuccess(Object result) {
      todoList = (List)result;
      saveTodoListInHistory();
      }

      public void onFailure(Throwable caught) {
      Todo todo =
      new Todo("ERROR!! Server could not be reached.");
      todoList.add(todo);
      saveTodoListInHistory();
      }
      };

      todoListBackupService.getTodoList(callback);
      }

      /**
      * Save the to-do list on the server.
      */
      private void saveTodoListOnServer() {
      saveTodoListInHistory();

      TodoListBackupServiceAsync todoListBackupService =
      (TodoListBackupServiceAsync)GWT.create(TodoListBackupService.class);

      ServiceDefTarget endpoint = (ServiceDefTarget)todoListBackupService;
      endpoint.setServiceEntryPoint("/todoListBackupService");

      AsyncCallback callback = new AsyncCallback() {
      public void onSuccess(Object result) {
      printTodoList();
      }

      public void onFailure(Throwable caught) {
      Window.alert("Warning : the to-do list could not be saved on the server. Maybe the server is down.");
      }
      };

      todoListBackupService.saveTodoList(todoList, callback);
      }
      示例應用程序在啟動時進行服務器端調用。該調用將返回用戶的 HttpSession 中保存的最新工作列表,或者包含“Hello from the server”工作的新工作列表:

      圖 12

      管理 Back 按鈕

      在高端 Web 應用程序中,瀏覽器的 Back 按鈕經常斷開。經典的 Ajax 應用程序不支持返回前一 Web 頁的標準 Web 行為。

      另一方面,GWT 允許對 Back 按鈕進行編程處理。這是一個功能強大卻又很難處理的特性,我們將在示例應用程序中對其進行探究。提議是將 Back 按鈕用作 Undo 按鈕:單擊該按鈕將顯示最新事件之前的工作列表。同樣地,Forward 按鈕將用作 Redo 按鈕。

      實施 HistoryListener 接口。要以編程方式管理 Back 按鈕,GWT 應用程序必須實施 com.google.gwt.user.client.HistoryListener 接口。這將強制編寫 onHistoryChanged(String _historyToken) 方法:

      public class TodoApp implements EntryPoint, HistoryListener {

      /**
      * This method is called whenever the application's history changes.
      */
      public void onHistoryChanged(String _historyToken) {
      if (Integer.parseInt(_historyToken) + 1 != historyToken) {
      if (historyMap.get(_historyToken) != null) {
      historyToken = Integer.parseInt(_historyToken);
      todoList = (List) historyMap.get(_historyToken);
      }
      }
      printTodoList();
      }
      該方法意味著當瀏覽器的歷史記錄更改時接收事件。您必須將其作為監聽器添加到 GWT 的 History 對象中。該操作通常在 onModuleLoad() 方法中完成,以便 History 對象在啟動時正確初始化:
       /**
      * This is the entry point method.
      */
      public void onModuleLoad() {

      History.addHistoryListener(this);

      }
      現在,每次瀏覽器的歷史記錄更改時都會調用 onHistoryChanged(String _historyToken) 方法。

      該方法可以根據作為參數傳遞的令牌重新創建應用程序的狀態。本例中,您將使用該令牌作為密鑰來查找存儲在歷史地圖中的工作列表。

      向歷史記錄中添加條目。要使 onHistoryChanged(String _historyToken) 方法起作用,您必須預先在歷史記錄中存儲一些條目。

      利用 History 對象很容易實現,可以使用其靜態 newItem(String historyToken) 方法:

      private void saveTodoListInHistory() {
      List todoListClone = new ArrayList();
      Iterator it = todoList.iterator();
      while (it.hasNext()) {
      Todo todo = (Todo) it.next();
      todoListClone.add(todo.clone());
      }
      historyMap.put(String.valueOf(historyToken), todoListClone);
      History.newItem(String.valueOf(historyToken));
      historyToken++;
      }
      在本例中,您將應用程序狀態存儲在了地圖中,因此使用歷史記錄令牌可以找到它。注意,您使用了一個數字作為歷史記錄令牌,也可以改用任何字符串。

      部署您的 Web 應用程序

      要部署通過 GWT 構建的 Web 應用程序,您需要編譯客戶端代碼,在 Web 應用程序的 .war 文件中打包結果,然后將 .war 文件部署到相應的應用服務器 OC4J 上。

      編譯客戶端代碼

      編譯客戶端代碼的方法有多種。使用 applicationCreator 腳本后,GWT 將創建一個名為 TodoApp-compile 的 shell 腳本。您可以從命令行啟動該腳本。與 TodoApp-shell 一樣,這是編譯應用程序的很好方法;但是,您可能更喜歡直接從 JDeveloper 內部啟動該腳本。

      另一種編譯代碼的方法使以托管模式執行應用程序,以便直接從 JDeveloper 編譯代碼。您的應用程序的窗口的工具欄包含編譯/瀏覽按鈕,與下圖類似:

      圖 13

      在編譯過程結束時,您的默認 Web 瀏覽器將打開以便您可以測試結果。GWT 開發 shell 的窗口將顯示編譯是否成功:

      圖 14

      無論您使用何種方法編譯代碼,您都可以在項目的 www/otn.todo.TodoApp 中找到生成的文件。

      最后一種編譯代碼的方法是使用 Ant。GWT 不提供特定的 Ant 任務,但是您可以通過標準的 Java Ant 任務啟動任何 Java 類(例如 GWTCompiler)。首先,定義包含 GWT jar 的路徑:


      <path id="project.class.path">
      <pathelement path="${java.class.path}/"/>
      <pathelement location="src"/>
      <pathelement path="/your/path/to/gwt-user.jar"/>
      <pathelement path="/your/path/to/gwt-dev-linux.jar"/>
      <!-- ... -->
      </path>
      現在,定義專用于編譯客戶端代碼的任務:
      <target name="GWTcompile">
      <java classpat
      classname="com.google.gwt.dev.GWTCompiler"
      fork="true">
      <arg value="-out"/>
      <arg value="${gwt.output.dir}"/>
      <arg value="${entry.point.class}"/>
      </java>
      </target>

      在屬性文件中設置 gwt.output.dir 和 entry.point.class 變量,如下所示:
      gwt.output.dir=www
      entry.point.class=otn.todo.TodoApp
      最后,在 Ant 腳本中聲明屬性文件(此處為 build.properties),如下所示:
      <property file="build.properties"/>
      您可以通過在任務的 Context 菜單中選擇 Run Target GWTCompile 直接啟動該新的目標:

      圖 15

        Apache Ant Log 窗口將顯示以下結果:

      GWTcompile:
      [java] Output will be written into www\otn.todo.TodoApp
      [java] Compilation succeeded

      BUILD SUCCESSFUL

      在 OC4J 中部署

      編譯完應用程序之后,在 OC4J 下部署它只需創建一個適當的部署配置文件。如果您按照前面描述的步驟進行操作,您應該已經具有一個默認的部署配置文件。如果沒有,只需選擇 File > New...> Deployment Profiles > WAR File,創建一個新的配置文件。

      使用您的配置,一切都應該正常工作。但是,如果您遇到任何問題,請查看以下常見的錯誤:

      • 在 Project Properties 的 Project Content > Web Application 中,HTML Root Directory 應該是應用程序的 www 目錄(在該目錄中,GWT 將對應用程序進行編譯以便在托管模式下運行)。
      • 在部署配置文件的 File Groups > WEB-INF/lib > Contributors 中,應該添加 gwt-user.jar。該 jar 文件包括 J2EE 規范中的 javax.servlet 程序包。這在本例中沒有引起任何問題;但是,您通常不應將這些類部署在 Web 應用程序中,因為它們會引起麻煩。如果發生了這種情況,GWT 還提供有一個 gwt-servlet.jar 文件,它是沒有 javax.servlet 程序包的 gwt-user.jar。
      • Web 應用程序的上下文根影響 GWT 的 RPC 機制。如果 GWT 客戶端應用程序要與服務器通信(如“使用 RPC 進行客戶端和服務器之間的數據交換”所述),它必須可以找到服務器。這就是我們已經討論過的 endpoint.setServiceEntryPoint("") 方法的目的。在本例中,我們將應用程序部署到了服務器的根上,這就是 GWT shell 默認的工作方式。但是,如果您將應用程序部署到 TodoApp Web 上下文(在部署配置文件的一般屬性中),請將端點設置為 /TodoApp/todoListBackupService 而不要設置為 /todoListBackupService。不用忘記該 URL 還應正確映射到應用程序的 web.xml 文件中(如前所述)。
      • 假設 OC4J 已在系統上正確安裝,將應用程序部署到服務器是很簡單的:只需右鍵單擊部署配置文件,并選擇 Deploy to OC4J。
      部署的應用程序有兩部分:
      • 客戶端應用程序是一組先前編譯的 HTML 和 JavaScript 文件。(請參見“編譯客戶端代碼”部分。)OC4J 充當經典的 Web 服務器,將這些文件傳遞給用戶。
      • 服務器端應用程序基本上是一個處理 RPC 通信的 servlet。在 OC4J 中部署后,該 servlet 可以訪問諸如 EJB 或 JMS 提供商等企業資源。
      性能智能化為靜態資源提供了高效服務;應用程序的主要性能瓶頸來源于客戶端/服務器通信。但是由于有 OC4J,我們可以訪問一些有趣的服務器端性能圖形:

      圖 16

      如該圖形所顯示的,在正常負載下(每秒幾個請求),應用程序的服務器端部分在平均不到 4 ms 的時間內進行響應,這是很難得的結果。
      posted on 2006-11-24 10:31 壞男孩 閱讀(2273) 評論(2)  編輯  收藏 所屬分類: 新知識學習

      FeedBack:
      # re: 使用 Oracle JDeveloper 構建您的第一個 GWT Web 應用程序
      2016-08-02 16:44 | 鄭州
      67786,,好  回復  更多評論
        
      # re: 使用 Oracle JDeveloper 構建您的第一個 GWT Web 應用程序
      2016-08-02 16:44 | 鄭州
      都回家一趟u  回復  更多評論
        
      主站蜘蛛池模板: 亚洲色最新高清av网站| 99视频在线精品免费观看6| 亚洲久悠悠色悠在线播放| 亚洲精品综合久久| 在线成人a毛片免费播放| 免费视频成人片在线观看| 亚洲一区在线免费观看| 亚洲一区二区三区偷拍女厕| 在人线av无码免费高潮喷水| 亚洲国产高清国产拍精品| 亚洲A∨无码一区二区三区| 高清在线亚洲精品国产二区| 成年女人毛片免费播放人| 蜜桃视频在线观看免费视频网站WWW| 亚洲一区二区三区播放在线| 亚洲三级电影网址| 亚洲日韩在线观看| 毛色毛片免费观看| 久久精品一本到99热免费| 一级成人a做片免费| 羞羞视频免费观看| 亚洲日韩一区精品射精| 日本高清免费中文字幕不卡| 1000部无遮挡拍拍拍免费视频观看| 久久嫩草影院免费看夜色| 亚洲日本在线观看网址| 亚洲成人黄色网址| 亚洲av福利无码无一区二区| 奇米影视亚洲春色| 77777亚洲午夜久久多人| 日韩亚洲精品福利| 亚洲av成人一区二区三区在线观看| 成人午夜免费福利视频| 国产一卡2卡3卡4卡2021免费观看 国产一卡2卡3卡4卡无卡免费视频 | 免费99精品国产自在现线| 一个人看的www免费视频在线观看| 国产免费福利体检区久久| 亚洲精品视频免费观看| 青青草国产免费国产是公开| 国产成人亚洲精品播放器下载| 亚洲熟妇AV一区二区三区宅男|