Một ý tưởng cũng giống như chỗ ngứa: bạn cần phải gãi nó và khi đó cảm thấy thỏa mãn hơn. Với vai trò là những nhà phát triển phần mềm, chúng ta dành nhiều thời gian nghĩ ra những ý tưởng cho các loại ứng dụng khác nhau. Thật là vui, phải vậy không? Nhưng cái khó là tìm ra cách để làm cho một sản phẩm phần mềm đơm hoa kết trái. Thật là hài lòng khi tưởng tượng ra một cái gì đó và sau đó tạo ra nó. Còn trái lại (một chỗ ngứa không được gãi) thì đúng là khó chịu thật.
Một lý do làm cho nhiều ứng dụng không bao giờ phát triển được là cần có một cơ sở hạ tầng. Một cơ sở hạ tầng được duy trì tốt thường liên quan đến một đội các nhà quản trị hệ thống, các nhà quản trị cơ sở dữ liệu (DBA) và các kỹ sư mạng, mà cho đến gần đây, vẫn là một hoạt động kinh doanh chủ yếu dành cho người giàu. Thậm chí trả tiền cho một bên thứ ba để cho lưu trú các ứng dụng của bạn cũng không đơn giản: điều gì sẽ xảy ra nếu bỗng nhiên ứng dụng nổi tiếng tăng vọt và có rất nhiều lượt truy cập? Cái gọi là hiệu ứng Slashdot (sự kiện số người truy cập đến trang Web bất thình lình tăng vọt) có thể vứt một ý tưởng tốt vào hố rác, đơn giản vì thật khó dự đoán những đột biến tải.
Tuy nhiên, như chúng ta đều biết, điều đó đang thay đổi. Những tiền đề cho các dịch vụ Web đã phát triển lên và ngày nay nó mang lại cho chúng ta những phương tiện, thông qua điện toán đám mây và người anh em tráng kiện hơn của nó, đó là nền tảng-như là-một dịch vụ (PAAS - platform-as-a-service), để xây dựng, triển khai và phân phối các ứng dụng dễ dàng hơn. Bây giờ, khi bạn viết Twitter (dịch vụ mạng xã hội miễn phí) tiếp theo và triển khai nó trên một nền tảng đám mây, nó sẽ có thể mở rộng, bạn thân mến ạ, mở rộng mãi.
Trong bài viết ba phần này, bạn sẽ học qua thực hành tại sao điện toán đám mây/PAAS là một bước nhảy tiến hóa quan trọng như vậy cho sự phát triển phần mềm, và đồng thời cũng bắt đầu với một nền tảng mới thú vị để phát triển Java: Máy ứng dụng của Google cho Java, hiện đang sẵn có dưới dạng phiên bản xem trước. Tôi sẽ bắt đầu với một tổng quan về Máy ứng dụng (App Engine) cho Java, bao gồm các kiểu dịch vụ ứng dụng mà nó cung cấp. Sau đó bạn sẽ đi thẳng vào một ví dụ ứng dụng — ví dụ đầu tiên trong hai ví dụ — bằng cách sử dụng trình cắm thêm của Google cho Eclipse làm Máy ứng dụng cho Java. Ví dụ ứng dụng đầu tiên sẽ sử dụng sự hỗ trợ của Máy ứng dụng cho Java đối với giao diện lập trình ứng dụng (API) dành cho Servlet Java và ví dụ ứng dụng thứ hai sẽ sử dụng sự hỗ trợ của nó đối với bộ công cụ Web của Google (GWT). Trong Phần 2, bạn sẽ tạo ra một ứng dụng quản lý liên lạc nhỏ bằng cách sử dụng sự hỗ trợ của Máy ứng dụng cho Java đối với các servlet và GWT, tương ứng. Và trong Phần 3, bạn sẽ sử dụng ứng dụng được xây dựng tuỳ chỉnh của bạn để khám phá sự hỗ trợ lưu giữ lâu bền dựa trên Java của Máy ứng dụng cho Java, sự hỗ trợ này dựa trên các đối tượng dữ liệu Java (Java Data Objects-JDO) và API dành cho lưu giữ lâu bền của Java (Java Persistence API - JPA).
Thôi, nói thế là đủ: Hãy rồ máy lên!
Về Máy ứng dụng của Google cho Java
Google (tôi tin rằng cũng là nhà sản xuất một số dạng máy tìm kiếm) đầu tiên đã phát hành Máy ứng dụng của Google trong tháng 4 năm 2008. Thật thất vọng với nhiều nhà phát triển Java, bản phát hành đầu tiên đã thuần túy là lĩnh vực của các lập trình viên Python — những người cho rằng khoảng trống nên được sử dụng cho các khối! (Tôi đã viết một cuốn sách về Python, vì vậy tôi biết rõ). Google đã đáp lại yêu cầu của đông đảo mọi người bằng cách phát hành Máy ứng dụng của Google cho Java trong tháng 4 năm 2009.
Máy ứng dụng của Google cho Java cung cấp một giải pháp xuyên suốt từ đầu đến cuối để phát triển ứng dụng Java doanh nghiệp: một giao diện người dùng đồ họa (GUI) Ajax dựa trên trình duyệt cho dễ sử dụng, hỗ trợ công cụ Eclipse và Máy ứng dụng của Google ở mặt sau. Tính dễ sử dụng và có công cụ đầy đủ cũng là các lợi thế của Máy ứng dụng của Google cho Java so với các giải pháp điện toán đám mây khác.
Phát triển ứng dụng trong Máy ứng dụng cho Java có nghĩa là sử dụng nguồn tài nguyên của Google để lưu trữ và lấy ra các đối tượng Java. Lưu trữ dữ liệu dựa trên BigTable, nhưng với các giao diện JDO và JPA cho phép bạn viết mã mà không bị ràng buộc trực tiếp với BigTable. Trong thực tế, Google cung cấp hỗ trợ dựa trên các tiêu chuẩn cho nhiều API để bạn có thể viết mã mà không bị ràng buộc 100% với nền tảng Máy ứng dụng cho Java.
Máy ứng dụng cho Java dựa trên các Java API tiêu chuẩn sau đây:
java.net.URLđể tìm nạp các dịch vụ (bằng cách giao tiếp với các máy chủ khác, sử dụng giao thức HTTP và HTTPS).- JavaMail để gửi thông điệp thư điện tử.
- Một giao diện JCache (JSR 107) cho bộ nhớ truy cập nhanh (Memcache) để cung cấp sự lưu trữ phân tán tạm thời, nhanh chóng để lưu trữ trong bộ nhớ truy cập nhanh (caching) các truy vấn và các tính toán.
Ngoài ra, Máy ứng dụng cho Java cung cấp hỗ trợ cho các dịch vụ ứng dụng sau đây:
- Xác thực và cấp quyền cho người dùng.
- CRON
- Nhập/xuất dữ liệu.
- Truy cập đến dữ liệu tường lửa.
Nhập/xuất dữ liệu là quan trọng cho việc di chuyển dữ liệu từ các
nguồn khác vào ứng dụng của Máy ứng dụng cho Java của bạn. Đây là một cách
khác mà bạn không bị ràng buộc với Máy ứng dụng cho Java. Hỗ trợ CRON của
Google được dựa trên một URL nội bộ, nhận các truy cập theo một lịch trình
nhất định, làm nó trở thành một dịch vụ tốt đẹp mà không có nhiều ràng
buộc với Máy ứng dụng cho Java. Cơ chế xác thực và cấp quyền cho người
dùng là đặc thù riêng cho Máy ứng dụng cho Java, nhưng bạn có thể
viết một ServletFilter, một khía cạnh, hoặc
trình cắm thêm An ninh Spring để giảm thiểu việc ghép buộc chặt chẽ
đó.
Tạo ứng dụng đầu tiên của bạn bằng Máy ứng dụng cho Java
Nếu bạn đọc đến đây thì bạn đã sẵn sàng để bắt đầu xây dựng ứng dụng đầu tiên của bạn bằng Máy ứng dụng cho Java. Bước đầu tiên của bạn là cài đặt trình cắm thêm Google (Plugin Google) cho Eclipse cho Máy ứng dụng cho Java; khi hoàn thành việc này, bạn có thể tiếp tục.
Mở Eclipse IDE của bạn và bạn sẽ thấy ba nút mới trong Eclipse IDE của bạn bên cạnh nút Printer (Máy in): một chữ G trong một quả bóng màu xanh, một G trong một hộp dụng cụ màu đỏ và một hình máy bay phản lực nhỏ của Máy ứng dụng cho Java, như trong Hình 1:
Hình 1. Các nút mới sáng lên trong Eclipse IDE của bạn
Đây là những gì các nút đó thực hiện:
- Quả bóng màu xanh cho phép bạn truy cập vào trình thủ thuật tạo dự án của Máy ứng dụng cho Java.
- Hộp dụng cụ màu đỏ cho phép bạn biên dịch một dự án GWT.
- Hình máy bay phản lực nhỏ là chìa khóa của bạn để triển khai một dự án Máy ứng dụng.
Bạn sẽ sử dụng trình thủ thuật tạo dự án để tạo ra hai dự án mới: một dựa vào các servlet và dự án kia được xây dựng bằng cách sử dụng GWT. Bạn sẽ sử dụng chức năng của hộp công cụ để biên dịch một dự án GWT. Bạn sẽ khởi chạy máy bay phản lực nhỏ khi bạn đã sẵn sàng triển khai dự án Máy ứng dụng, làm cho nó hoạt động.
Bây giờ bắt đầu bằng cách tạo ra một dự án của Máy ứng dụng cho Java. Trước tiên, hãy nhấn vào quả bóng màu xanh để truy cập vào trình thủ thuật tạo dự án. Sau đó, tạo một ứng dụng được gọi là SimpleServletApp bằng cách sử dụng gói có tên là gaej.example, như trong Hình 2:
Hình 2. Bắt đầu một dự án mới
Chú ý rằng người ta đã bỏ đánh dấu chọn hỗ trợ GWT cho ví dụ đơn giản đầu tiên này. Sau khi bạn hoàn thành bước này, trình thủ thuật tạo dự án sẽ tạo một ứng dụng đơn giản dựa trên servlet có một servlet kiểu “Xin chào thế giới”. Hình 3 cho thấy một ảnh chụp màn hình của dự án đó:
Hình 3. Dự án SimpleServletApp
Hãy chú ý các tệp JAR được tự động bao gồm cho dự án dựa trên servlet mới này:
- datanucleus-*.jar: Để truy cập vào kho lưu trữ dữ liệu của Máy ứng dụng cho Java sử dụng JDO tiêu chuẩn hoặc API của BigTable mức thấp.
- appengine-api-sdk.1.2.0.jar: Để sử dụng các dịch vụ ứng dụng của Máy ứng dụng cho Java chưa chuẩn như An ninh (Security) cho Máy ứng dụng cho Java.
- geronimo-*.jar: Để sử dụng các Java API tiêu chuẩn như API Quản lý giao dịch Java (JTA- Java Transaction Management API) và JPA.
- jdo2-api-2.3-SNAPSHOT.jar: Để sử dụng API JDO.
Bạn sẽ học cách sử dụng các API về lưu giữ lâu bền từ Máy ứng dụng cho Java và một số dịch vụ ứng dụng của Máy ứng dụng cho Java bắt đầu trong Phần 2 của bài viết này.
Cũng cần chú ý đến tệp cấu hình thùng chứa thời gian chạy cho Máy ứng dụng của Google, được gọi là appengine.xml. Trong ví dụ này, appengine.xml đang được sử dụng để đặt cấu hình tệp logging.properties để thực hiện đăng nhập với Máy ứng dụng cho Java.
Trước tiên hãy xem xét một ứng dụng servlet của Máy ứng dụng cho Java
Một khi bạn đã cấu hình tất cả mọi thứ trong trình thủ
thuật tạo dự án, Máy ứng dụng cho Java đưa ra cho bạn khung sườn của một
ứng dụng servlet kiểu Xin chào thế giới (Hello World). Hãy xem mã và sau
đó xem cách để chạy ứng dụng này như thế nào khi sử dụng các công cụ
Eclipse của Máy ứng dụng cho Java. Điểm vào chính của ứng dụng này là
SimpleServletAppServlet, như chỉ ra trong
Liệt kê
1:
Liệt kê 1. SimpleServletAppServlet
package gaej.example;
import java.io.IOException;
import javax.servlet.http.*;
@SuppressWarnings("serial")
public class SimpleServletAppServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
}
|
Servlet
này được ánh xạ với URI /simpleservletapp trong
web.xml, như được hiển thị trong Liệt kê 2:
Liệt kê 2. web.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>simpleservletapp</servlet-name>
<servlet-class>gaej.example.SimpleServletAppServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>simpleservletapp</servlet-name>
<url-pattern>/simpleservletapp</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
|
Trình thủ thuật tạo dự án cũng cung cấp một tệp index.html có một đường liên kết đến servlet mới, như chỉ ra trong Liệt kê 3:
Liệt kê 3. Trình thủ thuật tạo dự án tạo tệp index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- The HTML 4.01 Transitional DOCTYPE declaration-->
<!-- above set at the top of the file will set -->
<!-- the browser's rendering engine into -->
<!-- "Quirks Mode". Replacing this declaration -->
<!-- with a "Standards Mode" doctype is supported, -->
<!-- but may lead to some differences in layout. -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>Hello App Engine</title>
</head>
<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<!-- -->
<body>
<h1>Hello App Engine!</h1>
<table>
<tr>
<td colspan="2" style="font-weight:bold;">Available Servlets:</td>
</tr>
<tr>
<td><a href="simpleservletapp"/>SimpleServletAppServlet</td>
</tr>
</table>
</body>
</html>
|
Bây giờ bạn có một ứng dụng servlet đơn giản được xây dựng khi sử dụng chỉ một số các Java API. Và đó là điểm: Máy ứng dụng cho Java bao bọc chức năng Máy ứng dụng, sử dụng các Java API tiêu chuẩn, cho phép Máy ứng dụng hỗ trợ đông đảo các khung công tác sẵn có cho nền tảng Java.
Để chạy ứng dụng dựa trên servlet của bạn với các công cụ Eclipse của Máy ứng dụng cho Java, đầu tiên nhấn chuột phải vào dự án và chọn trình đơn Run As, sau đó chọn "Web Application" (Ứng dụng Web) có quả bóng màu xanh bên cạnh nó, như trong Hình 4:
Hình 4. Chạy máy chủ phát triển của Máy ứng dụng cho Java
Bây giờ bạn sẽ có thể chuyển hướng đến http://localhost:8080/simpleservletapp trong trình duyệt của bạn và xem ứng dụng đó với thông báo Xin chào thế giới.
Tạo một Máy ứng dụng cho ứng dụng Java/GWT
Bạn đã có một ý tưởng về cách một ứng dụng servlet đơn giản của Máy ứng dụng cho Java làm việc như thế nào, vì vậy tiếp theo chúng ta hãy khám phá công cụ Eclipse của Máy ứng dụng cho Java dành cho ứng dụng GWT. Bắt đầu bằng cách nhấn vào quả bóng màu xanh trên thanh công cụ của Eclipse IDE để kích hoạt trình thủ thuật tạo dự án của Google. Lần này, đánh dấu chọn hỗ trợ cho GWT, như trong Hình 5:
Hình 5. Tạo một ứng dụng GWT đơn giản với trình thủ thuật tạo dự án của Máy ứng dụng cho Java
Như bạn thấy trong Hình 6, Máy ứng dụng cho Java cung cấp nhiều tạo phẩm mã cho một ứng dụng GWT hơn là cho một ứng dụng dựa trên servlet đơn giản. Ứng dụng ví dụ là một GUI được làm trong GWT để trao đổi với một ứng dụng dịch vụ lời chào.
Hình 6. Các tạo phẩm mã được cung cấp cho một ứng dụng GWT
Có thêm một JAR nữa cho ứng dụng GWT mà nó là không cần thiết cho một ứng dụng dựa trên servlet, cụ thể là gwt-servlet.jar.
Các tạo phẩm khác như sau:
- src/gaej/example: SimpleGWTApp.gwt.xml: Bộ mô tả mô đun GWT.
- src/gaej.example.server: GreetingServiceImpl.java: Triển khai thực hiện dịch vụ lời chào.
- src/gaej.example.client: GreetingService.java: API đồng bộ cho dịch vụ lời chào.
- src/gaej.example.client: GreetingServiceAsync.java: API không đồng bộ cho dịch vụ lời chào.
- src/gaej.example.client: SimpleGWTApp.java: Điểm vào chính và cũng để xây dựng GUI của bộ khởi động.
- war/WEB-INF: web.xml: Triển khai bộ mô tả để cấu hình
GreetingServiceImpl. - war: SimpleGWTApp.html: Trang HTML hiển thị GUI của GWT.
- war: SimpleGWTApp.css: Bảng định kiểu cho GUI của GWT.
Trước khi đi sâu vào kiến trúc và mã nguồn của ứng dụng, hãy xem những gì sẽ xảy ra khi bạn chạy nó. Để chạy ứng dụng, nhấn vào hộp màu đỏ trên thanh công cụ của bạn, sau đó nhấn nút Compile (Biên dịch). Bây giờ nhấn chuột phải vào dự án và chọn mục trình đơn Run As—> Web Application như bạn đã làm trước đó. Lần này, vì bạn đang làm việc trên một ứng dụng GWT, một bàn giao tiếp trong chế độ lưu trú GWT (GWT Hosted Mode Console) và trình duyệt sẽ xuất hiện. Hãy tiếp tục và sử dụng ứng dụng Web để nhập tên của bạn và xem đáp ứng. Tôi đã nhận được đáp ứng như thấy trong Hình 7:
Hình 7. Chạy ứng dụng GWT mẫu
Trong các phần tiếp theo, tôi sẽ hướng dẫn bạn qua ứng dụng ví dụ GWT. Nếu bạn muốn biết thêm về GWT (hoặc học theo một hướng dẫn GWT), xem Tài nguyên.
Dựa vào cấu hình được cung cấp, các công cụ GWT của Eclipse tạo ra một ứng dụng bộ khởi động trình bày một mặt tiền trang HTML (SimpleGWTApp.html, hiển thị trong Liệt kê 10) Nó nạp simplegwtapp.js và simplegwtapp.nocache.js. Đây là mã JavaScript được GWT tạo từ mã Java của bạn, cụ thể là mã đã có trong thư mục src thuộc gói gaej.example.client (xem các Liệt kê 6, 7 và 8).
Điểm vào chính cho việc tạo GUI là
gaej.example.client.SimpleGWTApp, hiển thị
trong Liệt kê 8. Lớp này tạo các phần tử GUI của
GWT và kết hợp chúng với các phần tử HTML DOM trên SimpleGWTApp.html (xem
Liệt kê 10). SimpleGWTApp.html định nghĩa hai
phần tử DOM có tên là nameFieldContainer và
sendButtonContainer (các cột trong một
bảng). Lớp SimpleGWTApp sử dụng RootPanel.get("nameFieldContainer") để truy cập ô
kết hợp với các phần tử DOM đó và thay thế chúng bằng các phần tử GUI. Lớp
SimpleGWTApp sau đó định nghĩa một hộp văn
bản và một nút, mà bạn có thể sử dụng để nhập tên của một ai đó và gửi cho
họ một lời chào (xem Liệt kê 10).
GWT biết
rằng lớp SimpleGWTApp là điểm vào chính cho ứng
dụng vì SimpleGWTApp.gwt.xml chỉ rõ nó như vậy bằng phần tử điểm
vào.
SimpleGWTApp nối với nút, được
gọi là sendButton, sao cho khi nó được nhấn
SimpleGWTApp sẽ gọi phương thức greetServer trên GreetingService. Giao diện GreetingService được định nghĩa trong
src/gaej.example.client.GreetingService.java (Liệt kê
6).
Vì Ajax vốn là không đồng bộ, nên GWT định nghĩa một
giao diện không đồng bộ để truy cập các dịch vụ từ xa. SimpleGWTApp sử
dụng giao diện không đồng bộ được được định nghĩa trong
src/gaej.example.client.GreetingServiceAsync.java (Liệt kê 7). GreetingServiceImpl
(src/gaej.example.server.GreetingServiceImpl.java) thực hiện phương thức
greetServer được định nghĩa trong GreetingService (Liệt kê
5). Phương thức GreetingServiceImpl.greetServer trả về một chuỗi (String) mà SimpleGWTApp sử dụng chuỗi đó để hiển
thị thông báo lời chào trong hộp thoại do nó tạo ra.
Bộ mô tả mô
đun GWT khai báo điểm vào chính cho ứng dụng GUI, cụ thể là gaej.example.client.SimpleGWTApp, như thấy trong
Liệt kê
4:
Liệt kê 4. Bộ mô tả mô đun GWT (src/gaej/example/SimpleGWTApp.gwt.xml)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/ distro-source/core/src/gwt-module.dtd"> <module rename-to='simplegwtapp'> <!-- Inherit the core Web Toolkit stuff. --> <inherits name='com.google.gwt.user.User'/> <!-- Inherit the default GWT style sheet. You can change --> <!-- the theme of your GWT application by uncommenting --> <!-- any one of the following lines. --> <inherits name='com.google.gwt.user.theme.standard.Standard'/> <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> --> <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> --> <!-- Other module inherits --> <!-- Specify the app entry point class. --> <entry-point class='gaej.example.client.SimpleGWTApp'/> </module> |
GreetingServiceImpl là triển khai thực hiện thực
tế của ứng dụng dịch vụ lời chào, được hiển thị trong Liệt kê 5. Nó chạy
trên phía máy chủ và mã máy khách gọi nó qua một lời gọi thủ tục từ xa.
Liệt kê 5. Triển khai thực hiện các ứng dụng dịch vụ-lời chào (src/gaej.example.server.GreetingServiceImpl.java)
package gaej.example.server;
import gaej.example.client.GreetingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
/**
* The server side implementation of the RPC service.
*/
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
public String greetServer(String input) {
String serverInfo = getServletContext().getServerInfo();
String userAgent = getThreadLocalRequest().getHeader("User-Agent");
return "Hello, " + input + "!<br><br>I am running " + serverInfo
+ ".<br><br>It looks like you are using:<br>" + userAgent;
}
}
|
GreetingService, hiển thị trong Liệt kê 6, là
giao diện cho lời gọi thủ tục từ xa mà mã máy khách sử
dụng:
Liệt kê 6. API đồng bộ (src/gaej.example.client.GreetingService.java)
package gaej.example.client;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
/**
* The client side stub for the RPC service.
*/
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
String greetServer(String name);
}
|
GreetingServiceAsync là giao diện thực tế mà mã
máy khách sẽ sử dụng, như được chỉ ra trong Liệt kê 7. Mỗi phương thức đều
cung cấp một đối tượng gọi lại để cho bạn được thông báo một cách không
đồng bộ khi gọi cuộc gọi thủ tục từ xa hoàn thành. Dưới cái mui che này,
GWT sử dụng Ajax. Khi sử dụng Ajax trên máy khách này, tốt nhất là bạn
không chặn máy khách và vì vậy không chặn các cuộc gọi không đồng bộ. Việc
chặn máy khách sẽ làm hỏng mục đích sử dụng Ajax.
Liệt kê 7. API không đồng bộ (src/gaej.example.client.GreetingServiceAsync.java)
package gaej.example.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* The async counterpart of <code>GreetingService</code>.
*/
public interface GreetingServiceAsync {
void greetServer(String input, AsyncCallback<String> callback);
}
|
SimpleGWTApp là nơi mà hầu hết các hành động
xảy ra. Nó đăng ký cho các sự kiện GUI, sau đó sẽ gửi các yêu cầu Ajax đến
GreetingService này.
Liệt kê 8. Điểm vào chính này cho ứng dụng cũng xây dựng GUI khởi động (src/gaej.example.client.SimpleGWTApp.java)
package gaej.example.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class SimpleGWTApp implements EntryPoint {
/**
* The message displayed to the user when the server cannot be reached or
* returns an error.
*/
private static final String SERVER_ERROR = "An error occurred while "
+ "attempting to contact the server. Please check your network "
+ "connection and try again.";
/**
* Create a remote service proxy to talk to the server-side Greeting service.
*/
private final GreetingServiceAsync greetingService = GWT
.create(GreetingService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final Button sendButton = new Button("Send");
final TextBox nameField = new TextBox();
nameField.setText("GWT User");
// You can add style names to widgets
sendButton.addStyleName("sendButton");
// Add the nameField and sendButton to the RootPanel
// Use RootPanel.get() to get the entire body element
RootPanel.get("nameFieldContainer").add(nameField);
RootPanel.get("sendButtonContainer").add(sendButton);
// Focus the cursor on the name field when the app loads
nameField.setFocus(true);
nameField.selectAll();
// Create the popup dialog box
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Remote Procedure Call");
dialogBox.setAnimationEnabled(true);
final Button closeButton = new Button("Close");
// You can set the id of a widget by accessing its Element
closeButton.getElement().setId("closeButton");
final Label textToServerLabel = new Label();
final HTML serverResponseLabel = new HTML();
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
dialogVPanel.add(textToServerLabel);
dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
dialogVPanel.add(serverResponseLabel);
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
dialogVPanel.add(closeButton);
dialogBox.setWidget(dialogVPanel);
// Add a handler to close the DialogBox
closeButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
sendButton.setEnabled(true);
sendButton.setFocus(true);
}
});
// Create a handler for the sendButton and nameField
class MyHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the sendButton.
*/
public void onClick(ClickEvent event) {
sendNameToServer();
}
/**
* Fired when the user types in the nameField.
*/
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
sendNameToServer();
}
}
/**
* Send the name from the nameField to the server and wait for a response.
*/
private void sendNameToServer() {
sendButton.setEnabled(false);
String textToServer = nameField.getText();
textToServerLabel.setText(textToServer);
serverResponseLabel.setText("");
greetingService.greetServer(textToServer,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
dialogBox
.setText("Remote Procedure Call - Failure");
serverResponseLabel
.addStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(SERVER_ERROR);
dialogBox.center();
closeButton.setFocus(true);
}
public void onSuccess(String result) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel
.removeStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(result);
dialogBox.center();
closeButton.setFocus(true);
}
});
}
}
// Add a handler to send the name to the server
MyHandler handler = new MyHandler();
sendButton.addClickHandler(handler);
nameField.addKeyUpHandler(handler);
}
}
|
Bộ
mô tả triển khai Web (web.xml, như thấy trong Liệt kê 9) ánh xạ GreetingService như một nguồn tài nguyên Web dựa
trên servlet. Nó ánh xạ GreetingService dưới
tên /simplegwtapp/greet sao cho SimpleGWTApp có thể nạp nó và thực hiện cuộc gọi
đến nó. Bộ mô tả triển khai Web cũng biểu thị rằng SimpleGWTApp.html là
trang chào mừng cho ứng dụng, như vậy nó luôn luôn
nạp.
Liệt kê 9.Bộ mô tả triển khai để đặt cấu hình GreetingServiceImpl (war/WEB-INF/web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>SimpleGWTApp.html</welcome-file>
</welcome-file-list>
<!-- Servlets -->
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>gaej.example.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/simplegwtapp/greet</url-pattern>
</servlet-mapping>
</web-app>
|
Mặt tiền trang HTML là SimpleGWTApp.html, được hiển thị trong Liệt kê 10. Đây là trang để nạp simplegwtapp.js và simplegwtapp.nocache.js, là mã JavaScript được GWT tạo từ mã Java của bạn. Như đã đề cập ở trên, mã này lưu trữ trong thư mục src thuộc gói gaej.example.client (từ các Liệt kê 6, 7 và 8).
Liệt kê 10. Trang HTML để hiển thị GUI của GWT (war/SimpleGWTApp.html)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- The HTML 4.01 Transitional DOCTYPE declaration-->
<!-- above set at the top of the file will set -->
<!-- the browser's rendering engine into -->
<!-- "Quirks Mode". Replacing this declaration -->
<!-- with a "Standards Mode" doctype is supported, -->
<!-- but may lead to some differences in layout. -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -->
<!-- Consider inlining CSS to reduce the number of requested files -->
<!-- -->
<link type="text/css" rel="stylesheet" href="SimpleGWTApp.css">
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>Web Application Starter Project</title>
<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<script type="text/javascript" language="javascript"
src="simplegwtapp/simplegwtapp.nocache.js"></script>
</head>
<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<!-- -->
<body>
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
style="position:absolute;width:0;height:0;border:0"></iframe>
<h1>Web Application Starter Project</h1>
<table align="center">
<tr>
<td colspan="2" style="font-weight:bold;">Please enter your name:</td>
</tr>
<tr>
<td id="nameFieldContainer"></td>
<td id="sendButtonContainer"></td>
</tr>
</table>
</body>
</html>
|
Với GWT, bạn điều khiển dáng vẻ của ứng dụng của bạn thông qua CSS, như đã chứng tỏ trong Liệt kê 11:
Liệt kê 11. Bảng định kiểu cho GUI của GWT (war/SimpleGWTApp.css)
/** Add css rules here for your application. */
/** Example rules used by the template application (remove for your app) */
h1 {
font-size: 2em;
font-weight: bold;
color: #777777;
margin: 40px 0px 70px;
text-align: center;
}
.sendButton {
display: block;
font-size: 16pt;
}
/** Most GWT widgets already have a style name defined */
.gwt-DialogBox {
width: 400px;
}
.dialogVPanel {
margin: 5px;
}
.serverResponseLabelError {
color: red;
}
/** Set ids using widget.getElement().setId("idOfElement") */
#closeButton {
margin: 15px 6px 6px;
}
|
Triển khai Máy ứng dụng của Google
Một khi bạn đã tạo ra ứng dụng sát thủ tiếp theo của thế giới (vì chúng ta thực sự cần một ứng dụng lời chào thân thiện với người sử dụng), bạn sẽ muốn triển khai nó. Toàn bộ vấn đề sử dụng Máy ứng dụng của Google là bạn có thể triển khai ứng dụng của mình trên cơ sở hạ tầng vững chắc của Google, làm cho nó dễ dàng điều chỉnh hơn. Máy ứng dụng của Google được thiết kế để cung cấp một nền tảng cho việc xây dựng các ứng dụng có thể mở rộng "để phát triển từ một đến hàng triệu người dùng mà không nhức đầu về cơ sở hạ tầng" (như đã nêu trên trang chủ Máy ứng dụng - App Engine). Để sử dụng cơ sở hạ tầng này, bạn cần một tài khoản của Máy ứng dụng của Google cho Java.
Giống như nhiều thứ trong đời, thời gian đầu là miễn phí. Phiên bản miễn phí của Máy ứng dụng cho Java cung cấp cho ứng dụng đã triển khai đủ CPU, băng thông và lượng lưu trữ để phục vụ cho khoảng 5 triệu lượt truy cập trang. Sau đó, cần phải trả tiền khi bạn tiếp tục. (Cũng nên nhớ rằng cái sẵn có khi viết bài này là một bản phát hành xem trước của nền tảng Máy ứng dụng cho Java.)
Một khi bạn nhận được tài khoản, bạn sẽ thấy một danh sách còn bỏ trống các ứng dụng tại trang Web Máy ứng dụng cho Java. Nhấn vào nút Create New Application (Tạo ứng dụng mới) và một biểu mẫu giống như trong Hình 8 sẽ xuất hiện. Nhập tên ứng dụng duy nhất và một mô tả, sau đó bạn sẽ thấy một thông báo xác nhận với mã nhận dạng (identifier) ứng dụng của bạn.
Mã nhận dạng cũng thuộc về tệp app.yaml của ứng dụng của bạn.
Lưu ý rằng không thể thay đổi mã nhận dạng. Nếu bạn sử dụng việc xác thực
của Google cho các ứng dụng của bạn, thì "GAEj Article For Rick Part 1" sẽ
được hiển thị trong trang Sign In (Đăng nhập) khi bạn truy cập vào ứng
dụng của mình. Bạn sẽ sử dụng gaejarticleforrick để triển khai các ứng dụng lên Máy ứng dụng
của Google bằng trình cắm thêm Eclipse của Máy ứng dụng cho Java.
Hình 8. Tạo ứng dụng mới của Máy ứng dụng cho Java
Sau khi bạn thiết lập mã nhận dạng (ID) của ứng dụng, bạn có thể triển khai ứng dụng của mình từ Eclipse. Đầu tiên, nhấn vào nút của thanh công cụ trông giống như biểu tượng Máy ứng dụng của Google (một động cơ phản lực có cánh và đuôi), như chỉ ra trong Hình 9:
Hình 9. Trình cắm thêm Eclipse của Máy ứng dụng cho Java
Bạn có thể cần phải bảo đảm chắc chắn dự án Máy ứng dụng cho Java của bạn được đánh dấu chọn trước khi nhấn vào Deploy (Triển khai) trong hộp thoại như thấy trong Hình 10. Bạn sẽ được nhắc cung cấp mã ủy nhiệm Google của bạn, đó là địa chỉ và tên người dùng thư điện tử của bạn.
Hình 10. Triển khai dự án
Hộp thoại trong Hình 10 có một đường liên kết tới "App Engine Project
setting" (Thiết lập dự án Máy ứng dụng). Nhấn vào đường liên kết này (cũng
có thể truy cập từ tệp thiết lập dự án) và nhập ID của ứng dụng (trong
trường hợp này là gaejarticleforrick), như
trong Hình 11. Sau khi bạn điền vào ID của ứng dụng, nhấn OK, rồi
nhấn Deploy.
Hình 11. Thiết lập dự án cho máy ứng dụng của Google
Sau khi bạn đã triển khai ứng dụng của mình, nó sẽ có sẵn tại http://<application id>.appspot.com/. Bạn
cũng có thể thấy ứng dụng này đang hoạt động tại http://gaejarticleforrick.appspot.com/.
Đến đây kết thúc Phần 1 của bài giới thiệu của tôi về Máy ứng dụng của Google cho Java. Cho đến nay, bạn đã thu được một tổng quan về Máy ứng dụng cho Java là gì và đã thực hiện các bước đầu tiên bằng việc sử dụng Trình cắm thêm của Google cho Eclipse của Máy ứng dụng cho Java. Bạn tạo ra hai ứng dụng khởi động nhỏ (một ứng dụng dựa trên servlet còn cái kia dựa trên GWT) và sau đó đã triển khai ứng dụng GWT cho nền tảng của Máy ứng dụng Google này.
Các ví dụ cho đến nay đã chứng tỏ việc tạo công cụ và chức năng giúp Máy ứng dụng dễ dàng tạo và triển khai các ứng dụng Java mở rộng được — tiềm năng lên đến quy mô như của YouTube hoặc Facebook. Trong Phần 2, bạn sẽ tiếp tục khám phá những cơ hội sẵn có cho các nhà phát triển Java làm việc trên Máy ứng dụng cho Java. Rời khỏi các ví dụ ứng dụng đã trình bày trong bài viết này, bạn sẽ xây dựng một ứng dụng quản lý mối liên hệ tùy chỉnh. Ứng dụng này cũng sẽ là trọng tâm của các bài tập trong Phần 3, chúng đi sâu vào kho lưu trữ dữ liệu của Máy ứng dụng cho Java và mặt tiền GUI của nó.
Học tập
- "Máy ứng
dụng của Google cho Java, Phần 2: Xây dựng ứng dụng sát thủ" (Rick
Hightower, developerWorks, 08.2009): Tiếp tục khám phá những cơ hội sẵn có
cho các nhà phát triển Java đang làm việc trên Máy ứng dụng cho Java.
- "Xây dựng một ứng dụng Ajax khi sử dụng Bộ công cụ Web của Google,
Apache Derby và Eclipse, Phần 1: Mặt tiền vui mắt" (Noel Rappin,
developerWorks, 10.2006): Khởi động bài hướng dẫn bốn phần giới thiệu về
lập trình Ajax với Bộ công cụ Web của Google.
- "Nối đến đám mây, Phần 1: Sử dụng đám mây trong các ứng dụng"
(Mark O'Neill, developerWorks, 04.2009): Một tổng quan ba phần về các nền
tảng điện toán đám mây từ các nhà cung cấp lớn: Amazon, Google,
Microsoft® và SalesForce.com.
- Dự án
DataNucleus: Cung cấp các sản phẩm cho việc quản lý dữ liệu ứng
dụng trong một môi trường Java.
-
Trang chủ của Máy ứng dụng của
Google: Tìm hiểu thêm về Máy ứng dụng.
-
Các tài liệu Java của
Máy ứng dụng của Google: Thông tin thêm về việc phát triển Java
với Máy ứng dụng cho Java.
-
Nó có chạy được trong Máy ứng dụng cho Java không?: Tìm hiểu các
Java API tiêu chuẩn và các khung công tác nào tương thích với Máy ứng dụng
cho Java.
-
BigTable là gì?:
Đọc ấn phẩm nghiên cứu của Google để tìm hiểu.
- "GWT: Thông báo quan trọng
nhất tại JavaOne?" (Rick Hightower, Java Developers Journal,
06.2006): Thêm thông tin về lý do tại sao GWT cũng là một bước tiến cho
phát triển ứng dụng Java.
Lấy sản phẩm và công nghệ
-
Các trình cắm
thêm Eclipse của Máy ứng dụng cho Java: Tải về các trình cắm thêm
để bắt đầu.
-
Tài khoản của Máy ứng dụng: Bạn
sẽ cần một tài khoản để triển khai ứng dụng sát thủ của bạn khi sử dụng cơ
sở hạ tầng Máy ứng dụng của Google.
Thảo luận
-
Nhóm thảo
luận của Máy ứng dụng cho Java: Đăng ký vào nhóm này để đóng góp
và nhận sự giúp đỡ và lời khuyên khi bạn tìm hiểu về Máy ứng dụng cho
Java.
- Dành tâm trí cho cộng đồng My developerWorks.
Rick Hightower phục vụ với tư cách là giám đốc công nghệ cho Mammatus Inc., một công ty đào tạo chuyên về phát triển điện toán đám mây, GWT, Java EE, Spring và Hibernate. Ông là đồng tác giả của cuốn sách nổi tiếng Các công cụ Java cho lập trình cực biên (Java Tools for Extreme Programming) và tác giả của ấn bản đầu tiên của Struts Live — được tải về nhiều nhất trên TheServerSide.com trong nhiều năm. Ông cũng đã viết các bài báo và các hướng dẫn cho developerWorks của IBM và ở trong Ban biên tập của Tạp chí nhà phát triển Java, cũng như là một cộng tác viên thường xuyên về các chủ đề Java và Groovy trên DZone