Google Code 提供下列語言介面: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
雖然我們可以直接從 Java servlet 程式碼為使用者介面輸出 HTML,但是隨著 HTML 越來越複雜,維護將變得十分困難。建議您使用範本系統,其使用者介面已經過設計並實作至個別檔案,您只需要使用位置保留元和邏輯插入應用程式所提供的資料即可。我們為 Java 提供許多範本系統,且每個範本系統都能夠與「應用服務引擎」搭配使用。
在本教學課程中,我們將使用 JavaServer Page (JSP) 實作訪客留言板的使用者介面。JSP 屬於 servlet 標準。「應用服務引擎」會自動在應用程式的 WAR 中編譯 JSP 檔案,然後將它們對應至 URL 路徑。
我們的訪客留言板應用程式會將字串寫入輸出串流,不過這也可以寫成 JSP。讓我們將最新版本的範例移植到 JSP,從這個步驟著手。
在 war/ 目錄中,建立具備下列內容的 guestbook.jsp 檔案:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.google.appengine.api.users.User" %>
<%@ page import="com.google.appengine.api.users.UserService" %>
<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>
<html>
<body>
<%
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user != null) {
%>
<p>Hello, <%= user.getNickname() %>! (You can
<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">sign out</a>.)</p>
<%
} else {
%>
<p>Hello!
<a href="<%= userService.createLoginURL(request.getRequestURI()) %>">Sign in</a>
to include your name with greetings you post.</p>
<%
}
%>
</body>
</html>
按照預設,所有在 war/ 或子目錄 (除了 WEB-INF/ 以外) 中,名稱結尾為 .jsp 的檔案都會自動對應至 URL 路徑。URL 路徑為 .jsp 檔的路徑,包括檔名。這個 JSP 將自動對應至 URL /guestbook.jsp。
在訪客留言板應用程式中,我們希望以此做為應用程式的首頁,當人們存取 URL / 時即予以顯示。一個簡單的執行方法是,在 web.xml 中宣告 guestbook.jsp 為該路徑的「welcome」servlet。
編輯 war/WEB-INF/web.xml 並以此取代 <welcome-file-list> 目前的 <welcome-file> 元素。請務必從清單中移除 index.html,因為靜態檔案的優先性高於 JSP 和 servlet。
<welcome-file-list>
<welcome-file>guestbook.jsp</welcome-file>
</welcome-file-list>
提示:如果您使用的是 Eclipse,編輯器可能會使用「Design」(設計) 模式開啟這個檔案。如要使用 XML 模式編輯這個檔案,請選取框架下方的 [Source] (原始碼) 標籤。
停止再啟動開發伺服器。瀏覽下列 URL:
應用程式會顯示 guestbook.jsp 的內容,包括使用者的暱稱 (如果使用者已登入)。
當您首次載入 JSP 時,開發伺服器會將 JSP 轉換成 Java 原始程式碼,然後將 Java 原始碼編譯成 Java 位元組碼。Java 原始碼和經過編譯的類別會儲存至暫存目錄。如果原始的 JSP 檔案遭到變更,開發伺服器將自動重新產生與編譯 JSP。
當您將應用程式上傳至「應用服務引擎」時,SDK 會將所有的 JSP 編譯成位元組碼,然後只上傳位元組碼。當您的應用程式在「應用服務引擎」上執行時,它會使用經過編譯的 JSP 類別。
我們的訪客留言板應用程式需要網頁表單,以便使用者張貼新的訊息,另外它還需要表單處理方法。表單的 HTML 會嵌入 JSP。表單的目的地會是一個新的 URL (/sign),而這個 URL 將由新的 servlet 類別 (SignGuestbookServlet) 負責處理。SignGuestbookServlet 會處理表單,然後將使用者的瀏覽器重新導向 /guestbook.jsp。 就目前來說,新的 servlet 會將張貼的訊息寫入記錄。
編輯 guestbook.jsp,並在結尾的 </body> 標記上方加入下列程式碼:
...
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Post Greeting" /></div>
</form>
</body>
</html>
在 guestbook 套件中建立 SignGuestbookServlet 新類別。(非 Eclipse 使用者,請在 src/guestbook/ 中建立 SignGuestbookServlet.java 檔案)。請為來源檔案設定下列內容:
package guestbook;
import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
public class SignGuestbookServlet extends HttpServlet {
private static final Logger log = Logger.getLogger(SignGuestbookServlet.class.getName());
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String content = req.getParameter("content");
if (content == null) {
content = "(No greeting)";
}
if (user != null) {
log.info("Greeting posted by user " + user.getNickname() + ": " + content);
} else {
log.info("Greeting posted anonymously: " + content);
}
resp.sendRedirect("/intl/zh-TW/guestbook.jsp");
}
}
編輯 war/WEB-INF/web.xml 並添加下列程式碼以宣告 SignGuestbookServlet servlet,然後將它對應至 /sign URL:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
...
<servlet>
<servlet-name>sign</servlet-name>
<servlet-class>guestbook.SignGuestbookServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sign</servlet-name>
<url-pattern>/sign</url-pattern>
</servlet-mapping>
...
</web-app>
這個新的 servlet 使用 java.util.logging.Logger 類別,將訊息寫入記錄。您可以使用 logging.properties 檔案控制這個類別的行為,以及在應用程式的 appengine-web.xml 檔案中所設定的系統屬性。如果您使用的是 Eclipse,您的應用程式會使用這個檔案 (位於應用程式的 src/ 中) 的預設版本以及適當的系統屬性完成建立。
如果您使用的不是 Eclipse,您必須手動設定 Logger 設定檔。將範例檔案從 SDK 的 appengine-java-sdk/config/user/logging.properties 複製到應用程式的 war/WEB-INF/ 目錄。然後,按照所述指示,編輯應用程式的 war/WEB-INF/appengine-web.xml 檔:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
...
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
Servlet 會使用 INFO 記錄等級 (使用 log.info()) 記錄訊息。預設的記錄等級為 WARNING,它會抑制來自輸出的 INFO 訊息。如要變更 guestbook 套件中所有類別的記錄等級,請編輯 logging.properties 檔並新增 guestbook.level 的項目,如下所示:
.level = WARNING guestbook.level = INFO ...
提示:當「應用服務引擎」的執行應用程式透過 java.util.logging.Logger API 記錄訊息時,「應用服務引擎」會記錄訊息,且可以透過「管理控制台」顯示記錄,也可以透過 AppCfg 工具提供下載。「管理控制台」可讓您按照記錄等級瀏覽訊息。
重新建置與重新啟動,然後測試 http://localhost:8080/。表單隨即顯示。在表單輸入一些文字,然後提交。瀏覽器會將表單傳送給應用程式,然後重新導向空白表單。伺服器會將您輸入的訊息資料記錄到控制台。
我們有一個使用者介面,可提示使用者輸入訊息。現在,我們需要一種方法記住使用者張貼的訊息,再向其他的訪客顯示。為此,我們將使用「應用服務引擎」資料存放區。
繼續瀏覽「透過 JDO 使用資料存放區」一節。