Phát triển Java 2.0: Chào Google App Engine

Phát triển ứng dụng Web nhanh chóng bằng cách sử dụng Groovy, Eclipse và JDO

Các giải pháp nguồn mở và các cơ sở hạ tầng vay mượn đang thay đổi đặc điểm của việc phát triển Java™, cho phép bạn cung cấp phần mềm tốt hơn, nhanh chóng hơn và với chi phí thấp. Andrew Glover, khi đặt ra thuật ngữ Java development 2.0 (phát triển Java 2.0) để gói gọn sức mạnh tích lũy của các hiện tượng này, đã khởi đầu một loạt bài viết mới về một số công cụ và công nghệ có liên quan. Bài viết đầu tiên này báo hiệu thời kỳ phát triển Java 2.0 đã tới và giải thích cho bạn cách để có thể làm cho những khái niệm của nó đơm hoa kết trái nhanh chóng với Google App Engine (Máy ứng dụng của Google) cho Java.

Andrew Glover , Tác giả và nhà phát triển, ThirstyHead.com

Andrew GloverAndrew Glover là một nhà phát triển, tác giả, diễn giả và nhà doanh nghiệp với một niềm đam mê phát triển hướng hành vi (Behavior-Driven Development), Tích hợp liên tục và phát triển phần mềm nhanh nhẹn (Agile).



04 12 2009

Thế giới Java là một hệ sinh thái phong phú với một bố cục trải rộng gồm các nhà phát triển, các doanh nghiệp và — quan trọng nhất — các ứng dụng, nhiều ứng dụng đã hoàn thiện trong hơn một thập kỷ qua. Cộng đồng Java trên toàn thế giới đã đầu tư rất nhiều tiền bạc, thời gian và trí lực vào nền tảng này và những đóng góp này đã mang lại một kho tàng giàu có các công cụ mã nguồn mở và các công cụ thương mại, các khung công tác, và thực sự cả các giải pháp, rất thành công.

Hàng loạt đầu tư như nói trên vào nền tảng Java đã thay đổi cách phát triển Java một cách khéo léo. Hai xu hướng chính đang thay đổi nhanh chóng đặc điểm của nó:

Về loạt bài này

Bối cảnh phát triển Java đã thay đổi căn bản kể từ công nghệ Java đầu tiên xuất hiện. Nhờ sự hoàn thiện các khung công tác mã nguồn mở và các cơ sở hạ tầng triển khai cho-thuê đáng tin cậy, giờ đây có thể lắp ráp, thử nghiệm, chạy và bảo trì các ứng dụng Java một cách nhanh chóng và không tốn kém. Trong loạt bài này, Andrew Glover khám phá một loạt các công nghệ và các công cụ làm cho mô hình phát triển Java mới này trở thành có thể.

  • Lợi dụng hoàn toàn các công cụ và các khung công tác mã nguồn mở để xây dựng các ứng dụng từ trên xuống dưới.
  • Thuê (hoặc mượn) các cơ sở hạ tầng ứng dụng cần thiết ở mọi cấp độ để quản lý vòng đời phần mềm, bao gồm cả việc tự chạy các ứng dụng.

Không khía cạnh nào trong những gì tôi gọi phát triển Java 2.0 là mới hoặc cách mạng, nhưng các công nghệ cho phép đã hoàn thiện đến mức bây giờ đã có thể, như chưa từng có trong lịch sử của công nghệ Java, lắp ráp các ứng dụng tốt hơn một cách nhanh chóng rẻ — chắc chắn là một trong những mong muốn trên hết của các doanh nghiệp trên thế giới.

Bài viết này khởi đầu một loạt bài viết mới sẽ tìm hiểu việc phát triển Java 2.0 sâu hơn. Bạn sẽ tìm hiểu về việc xây dựng và triển khai các ứng dụng Web với EC2 của Amazon, sử dụng Google App Engine (máy ứng dụng của Google), sử dụng CouchDB (đang được gọi là cơ sở dữ liệu cho Web) và các công cụ và các công nghệ khác cung cấp các khối xây dựng để lắp ráp, thử nghiệm và triển khai các ứng dụng nhanh gọn và chi phí ít tiền hơn so với từ trước đến bây giờ.

Điểm dừng đầu tiên: Google App Engine cho Java (xem Tài nguyên). Tôi sẽ giới thiệu cho bạn nền tảng này bằng phương pháp "Hello World" (Xin chào Thế giới) truyền thống, sau đó chỉ cho bạn cách tạo một ứng dụng Web hoạt động bằng cách sử dụng Groovy, Java Data Objects (JDO-Các đối tượng dữ liệu Java) và trình cắm thêm Eclipse cho Google App Engine. Tuy nhiên, theo trình tự, trước tiên hãy xem tổng quan nhanh về giá trị kinh doanh của việc phát triển Java 2.0.

Nhanh và rẻ

Các từ nhanhrẻ thường không được kết hợp với việc phát triển Java. Trong thực tế, chúng thường gợi lên các ấn tượng về phát triển phần mềm ít quan trọng — tầm nhìn của các công ty nhỏ có ít nguồn lực. Tuy nhiên, sự thật của vấn đề là CNTT là một trọng tâm chi phí đối với nhiều công ty (lớn và nhỏ), thúc đẩy họ giữ cho các chi phí CNTT thấp trong khi rút ra càng nhiều giá trị càng tốt.

Đó là nơi việc phát triển Java 2.0 vào cuộc. Bằng cách sử dụng các công cụ mã nguồn mở, các khung công tác và thậm chí các giải pháp, các công ty có thể lắp ráp các ứng dụng phần mềm nhanh chóng vì họ không phải tự mình viết nhiều mã lệnh. Khi lần đầu tiên tôi bắt đầu phát triển phần mềm bằng công nghệ Java hơn 10 năm trước đây, phạm vi của các công cụ và các khung công tác có sẵn cho các nhà phát triển nhỏ bé hơn nhiều. Một số ít các công cụ đó cũng không có sẵn miễn phí. Bạn phải mua một IDE, một cơ sở dữ liệu, một khung công tác ánh xạ đối tượng-quan hệ (ORM) (ôi chết tiệt, bạn có thể đã phải mua trình điều khiển cần thiết để giao tiếp với cơ sở dữ liệu của bạn) và dĩ nhiên, các máy để triển khai ứng dụng của bạn trên đó. Bây giờ? Tất cả mọi thứ mà tôi vừa liệt kê (và nhiều hơn nữa) là có sẵn miễn phí và chất lượng cao.

Hơn nữa, bằng cách vay mượn cơ sở hạ tầng (ví dụ như những cơ sở hạ tầng được EC2 của Amazon hoặc Google App Engine cung cấp), bạn có thể triển khai ứng dụng khá rẻ (so với mua toàn bộ cơ sở hạ tầng cần thiết).

Xây dựng, mua, hay mượn: Đó là câu hỏi mới

Nhiều doanh nghiệp có cả một danh sách phần cứng để chạy các ứng dụng như các cơ sở dữ liệu, các máy chủ ứng dụng, các hệ thống quản lý thay đổi và các công cụ lần vết tìm lỗi. Tuy vậy, ngày nay, danh sách này có thể dễ dàng vứt bỏ để thay bằng việc sử dụng chính gói phần mềm ấy dưới dạng một dịch vụ đang chạy trên một cơ sở hạ tầng của người nào đó khác.

Toàn bộ chồng ứng dụng mà một nhóm làm việc có thể phải sử dụng để quản lý một quá trình phát triển có thể được vay mượn — nghĩa là, thuê với một khoản phí nhỏ — giải phóng cho công ty khỏi phải đầu tư vào phần cứng để chạy chúng. Ví dụ, thay vì mua một máy tính để chạy một hệ thống quản lý thay đổi (như Subversion hoặc Git, cả hai là mã nguồn mở và có sẵn miễn phí), một nhóm làm việc có thể sử dụng một dịch vụ quản lý thay đổi dùng chung như GitHub. Công ty đằng sau GitHub phải gánh chịu chi phí của các tài sản phần cứng và tính một chi phí danh nghĩa (thường là hàng tháng cho mỗi người dùng) cho các tổ chức khác sử dụng Git. Cùng một nguyên tắc thuê phần mềm như là một dịch vụ từ các nhà cung cấp khác như thế này có thể được áp dụng cho việc lần vết tìm lỗi, quản lý các bài kiểm thử và quản lý các yêu cầu (ví dụ qua JIRA Hosted hoặc Pivotal Tracker).

Cũng có thể nói giống như vậy đối với các tài sản phần cứng nằm dưới mà các nền tảng phần mềm khác (về bản chất, thường là tùy chỉnh) chạy trên đó. Một doanh nghiệp có thể vứt bỏ phần cứng nằm bên dưới của một ứng dụng web cụ thể để thay bằng việc chạy ứng dụng trên phần cứng được cung cấp bởi Amazon, Google hoặc các đối tác khác. Các công ty này đưa ra khả năng thuê phần cứng ở các mức độ khác nhau, vừa vặn có thể lưu trữ một ứng dụng. Hơn nữa, các công ty này quản lý khả năng mở rộng, sao lưu và thậm chí cả an ninh nữa. Hãy suy nghĩ về nó một lát: Amazon và Google đã nêu ra những mối quan tâm này (và nhiều hơn nữa) từ lâu rồi và đối phó tốt hơn với chúng, có nhiều đổi mới xung quanh các khía cạnh của việc chạy các nền tảng phần mềm sao cho hiệu quả. (Đó là đúng. Hãy đương đầu với nó).

Bằng cách sử dụng App Engine của Google, ví dụ thế, một công ty CNTT có thể hạ thấp tổng chi phí mua một cơ sở hạ tầng để chạy các ứng dụng cần thiết. Và họ có thể triển khai các ứng dụng đó nhanh hơn vì vô số các mối quan tâm đan chéo nhau, kết hợp với việc triển khai ứng dụng và quản lý đã được tính đến và vì thế được cung cấp cho họ (với nhiều khả năng là theo một cách tốt hơn).

Nhanhrẻ không còn có nghĩa là chất lượng thấp. Ngược lại, phát triển Java 2.0 là một cách tiếp cận chiến thuật đã giả định một quy trình vững chắc để nhấn mạnh chất lượng.


Một ngày đơn giản với App Engine của Google

App Engine của Google là một nền tảng thực sự để xây dựng và triển khai ứng dụng Web Java (và Python) trên cơ sở hạ tầng mở rộng của Google. Nó không yêu cầu lệ phí cấp phép sử dụng (tất nhiên, trừ ra một số thư viện phần mềm mà bạn chọn để sử dụng trên cơ sở hạ tầng ấy yêu cầu giấy phép) và không cần chi phí trả trước cho băng thông hoặc không gian lưu trữ. Cơ sở hạ tầng của App Engine là hoàn toàn miễn phí cho đến khi bạn đạt đến ngưỡng về mức sử dụng — dung lượng lưu trữ 500MB và, theo như trích dẫn nguyên văn từ Google, "đủ CPU và băng thông cho khoảng 5 triệu lượt xem trang mỗi tháng". Chỉ cần nói rằng, khi bạn đạt tới điểm mà Google bắt đầu gửi hóa đơn tính phí cho bạn, ứng dụng Web của bạn rõ ràng đã tạo ra lưu lượng đáng kể (và do đó có lãi).

Dựng lên một ứng dụng và chạy nó trên App Engine không thể dễ dàng hơn nữa. Google thậm chí còn cung cấp một trình cắm thêm Eclipse xử lý gần như mọi thứ cho bạn. Và trình cắm thêm này bao gồm các thành phần thiết yếu của một ứng dụng servlet "Hello World" để giúp bạn bắt đầu với nền tảng này. Trong bài giới thiệu nhập môn gần đây của ông trên developerWorks ("App Engine của Google cho Java, Phần 1: Tăng tốc nó!") Rick Hightower sẽ đưa bạn qua từng bước triển khai ứng dụng Hello World (bao gồm các ảnh chụp màn hình). Nếu bạn chưa từng làm việc theo bài viết của Rick, hãy làm theo các bước sau:

Xác định phiên bản

Các triển khai App Engine có thể được định phiên bản — đó là, bạn có thể gán một mẫu chuỗi ký tự (biểu hiện một phiên bản) cho một bản triển khai. Điều này có ích khi bạn bắt đầu có nhiều bản phát hành. Thông qua các URL và bảng điều khiển của Google, bạn có thể mô tả phiên bản nào là phiên bản "hoạt động" và phiên bản nào không phải là phiên bản hoạt động (mặc dù bất kỳ bản triển khai đã xác định phiên bản nào đều vẫn có thể truy cập qua một URL, với điều kiện bạn chưa gỡ bỏ nó trước). Theo đó, bất cứ lúc nào bạn muốn triển khai một phiên bản mới của dự án của bạn lên cơ sở hạ tầng của Google, bạn phải cung cấp cho bản triển khai đó một mã hiệu phiên bản hợp lệ. Mẫu chuỗi ký tự không được bao gồm các dấu chấm câu (1.1 không dùng được, nhưng 1-1 lại dùng được). Bạn có thể gán các phiên bản trong tệp AppEngine-web.xml, có trong thư mục war/WEB-INF đã được sinh ra khi bạn tạo lập một dự án mới. Để triển khai dự án đầu tiên của mình, bạn không cần phải đối phó với các phiên bản (chưa cần) vì Google chỉ định một phiên bản khởi đầu là 1 trong tệp appengine-web.xml đã tạo ra.

  1. Hãy tạo một tài khoản App Engine của Google (nó là miễn phí) bằng cách nhấn vào liên kết Sign up (Đăng nhập) trong Getting Started (Bắt đầu) trên trang http://code.google.com/appengine/.
  2. Tải xuống trình cắm thêm App Engine của Google cho Eclipse từ http://code.google.com/appengine/downloads.html và cài đặt nó.
  3. Tạo một dự án mới bằng cách nhấn vào nút New Web Application Project (Dự án ứng dụng Web mới) trong Eclipse, trong hộp thoại kết quả, bỏ dấu chọn của tùy chọn Use Google Web Toolkit (sử dụng dụng cụ Web của Google). Đặt tên dự án và gói tương ứng là bất cứ cái gì bạn muốn.
  4. Chọn dự án của bạn trong hệ thống phân cấp và nhấn vào nút Deploy App Engine Project (Triển khai dự án App Engine).
  5. Nhập mã ủy quyền của bạn (là cái mà bạn đã sử dụng khi tạo ra một tài khoản App Engine trong Bước 1).
  6. Kết hợp dự án cục bộ của bạn với mã nhận dạng (ID) của ứng dụng mà bạn tạo ra khi bạn bước đầu tạo một tài khoản App Engine. (Bạn có thể có đến 10 ID).
  7. Nhấn vào nút Deploy (Triển khai). Bạn sẽ thấy rất nhiều văn bản trôi qua trên bàn điều khiển Eclipse (trình cắm thêm đang thực hiện rất nhiều đằng sau hậu trường bao gồm việc cải tiến mọi lớp cần thiết nào để sử dụng dịch vụ lưu trữ-dữ liệu rất ấn tượng của Google). Khi tiếng ồn dịu dần (và tất cả mọi thứ đã làm việc đúng), bạn sẽ thấy một thông báo kết thúc bằng dòng chữ "Việc triển khai đã hoàn tất thành công."
  8. Đi tới trang tài khoản App Engine của bạn tại Google và tìm liên kết Versions trên bảng điều khiển của Google. Ở đó bạn sẽ thấy phiên bản đã triển khai của bạn và URL tương ứng của nó. Nhấn vào URL và sau đó nhấn vào liên kết tới servlet đã tạo ra để thấy dòng chữ "Hello, world" (Xin chào, thế giới) buồn tẻ nhưng lại làm bạn hài lòng làm sao, được in ra dạng văn bản.

Ít dòng mã hơn với Groovlets

Bạn đã triển khai thành công ứng dụng Google App Engine đầu tiên của bạn và bạn đã không viết một dòng mã nào. Thực vậy, nếu bạn có kế hoạch sử dụng App Engine, bạn sẽ đi đến chỗ viết một số dòng mã — nhưng hãy nhớ rằng, đã có nhiều mã ở đó mà bạn có thể tái sử dụng để làm cho công việc của bạn dễ dàng hơn. Mã tái sử dụng đó có thể là các dịch vụ mà Google cung cấp (chẳng hạn như các dịch vụ tài khoản Google hoặc dịch vụ lưu trữ dữ liệu của nó) hoặc các thư viện nguồn mở đã được chuyển đến để làm việc trên cơ sở hạ tầng của Google. Việc dùng lại mã của người khác thường có nghĩa là bạn viết mã ít hơn — và ít mã hơn rất có thể có nghĩa là có ít lỗi hơn.

Một trong những thư viện nguồn mở yêu thích của tôi (và thực ra là các nền tảng) hầu như luôn dẫn đến ít dòng mã hơn để tạo ra các ứng dụng làm việc là Groovy (xem Tài nguyên). Nhóm Groovy gần đây đã phát hành các phiên bản của nền tảng này để làm việc trên App Engine, cho phép bạn sử dụng Groovlets thay vì các servlet làm cho một ứng dụng hoạt động nhanh gọn. Groovlets là các kịch bản lệnh Groovy đơn giản hành động như các servlet. Vì bạn đã có một servlet để in "Hello, world", tôi sẽ chỉ cho bạn cách làm điều tương tự với một Groovlet sẽ dễ dàng như thế nào (và bạn sẽ thấy Groovy cho phép ít hơn bao nhiêu dòng mã).

Việc triển khai một Groovlet trên App Engine với trình cắm thêm Eclipse diễn ra theo một vài bước đơn giản:

  1. Tải về phiên bản mới nhất của Groovy (tại thời điểm bài viết này là 1.6.3) từ http://groovy.codehaus.org/Download.
  2. Tìm tệp groovy-all-1.6.3.jar và đặt nó vào thư mục war/WEB-INF/lib của dự án App Engine của bạn. Tiện thể, trong thư mục này, bạn có thể đặt bất kỳ thư viện nào mà ứng dụng của bạn yêu cầu (với một số cảnh báo mà tôi sẽ trình bày ngay sau đây).
  3. Thêm các câu trong Liệt kê 1 (để ánh xạ Groovlets tới các yêu cầu chuyên dùng) vào tệp web.xml, có trong thư mục war/WEB-INF:
    Liệt kê 1. Cập nhật tệp web.xml để hỗ trợ Groovlets
    <servlet>
     <servlet-name>GroovyServlet</servlet-name>
     <servlet-class>groovy.servlet.GroovyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
     <servlet-name>GroovyServlet</servlet-name>
     <url-pattern>*.groovy</url-pattern>
    </servlet-mapping>
  4. Thêm một thư mục groovy vào thư mục WEB-INF của bạn; đây là nơi bạn sẽ lưu Groovlets của mình. Trong thư mục groovy, tạo một tệp mới gọi là helloworld.groovy. Trong tệp mới đó, gõ nhập println "Hello, Groovy baby!"
  5. Cập nhật phiên bản của ứng dụng của bạn — gọi là 1-1 — và triển khai lại. Tìm URL tương ứng qua bảng điều khiển Google và sau đó lướt tới /helloworld.groovy trong trình duyệt của bạn và thưởng thức sự lộng lẫy của một thông báo hợp thời được in từ Groovy trên cơ sở hạ tầng của Google.

Điều đó thật dễ dàng, phải không? Tất cả những thứ mà bạn phải làm chỉ là thêm vào Groovy JAR, cập nhật tệp web.xml, tạo một thư mục groovy mới, viết một Groovlet và triển khai nó. Bạn có nhận thấy Groovlet đã làm cũng những việc tương tự như servlet mặc định mà trình cắm thêm đã tạo ra nhưng chỉ trong một dòng mã không? Bạn chọn sẽ phải viết và duy trì cái nào: một lớp lớn hay một lớp nhỏ mà làm cùng một việc?


Groovy + Java = ứng dụng hoạt động. Rất nhanh chóng.

Bây giờ tôi sẽ chỉ cho bạn việc sử dụng Groovy cùng với App Engine của Google có thể mang lại một ứng dụng hoạt động nhanh gọn như thế nào. Tôi sẽ sử dụng một trang HTML đơn giản, một Groovlet và một lớp Java có tăng cường JDO để lưu giữ lâu bền một sự kiện (trong trường hợp này, một cuộc thi ba môn phối hợp). Tôi sẽ giữ cho nó đơn giản vào lúc này, nhưng bạn sẽ thấy rằng ứng dụng này có thể phát triển thêm để bao gồm các đặc tính khác và trong các bài viết tiếp theo của loạt bài này bạn sẽ thực hiện chúng (tất nhiên, sử dụng các cơ sở hạ tầng và các công nghệ khác).

JDO nhanh

Google App Engine cung cấp khả năng để lưu giữ lâu bền dữ liệu khi sử dụng JDO, là một tiêu chuẩn Java cho lưu giữ lâu bền (xem Tài nguyên). Đối với hầu hết các nhà phát triển Java, lưu giữ lâu bền dữ liệu thường ngụ ý việc ghi lưu thông tin vào một cơ sở dữ liệu quan hệ; tuy nhiên, trong trường hợp của Google, cơ chế lưu trữ nằm dưới là sở hữu độc quyền của Big Table, không phải là cơ sở dữ liệu quan hệ. Điều vừa nói không thực sự quan trọng: các chi tiết về cách Google lưu giữ lâu bền các thuộc tính cụ thể phần lớn được ẩn dấu với bạn. Chỉ cần nói rằng, bạn có thể sử dụng các đối tượng Java bình thường (hoặc các đối tượng Groovy, cho vấn đề này) để xây dựng một ứng dụng có thể lưu trữ thông tin như bạn sẽ làm trong bất kỳ ứng dụng nào khác. Vừ̀a vặn trong trường hợp của Google, bạn phải sử dụng JDO. (Hibernate, được cho là̀ một khung công tác ORM phổ biến cho Java, không làm việc với App Engine.)

JDO là khá đơn giản. Bạn tạo các POJO — Plain Old Java Objects (các đối tượng thuần Java) (có thể các có mối quan hệ với các đối tượng Java khác) — mà bạn khai báo có khả năng lưu giữ lâu bền thông qua chú giải mức lớp @PersistenceCapable. Bạn xác định các thuộc tính nào của đối tượng được lưu giữ lâu bền qua các chú giải @Persistent. Ví dụ, tôi muốn lưu trữ các sự kiện thi đấu ba môn phối hợp (lúc này tôi sẽ tập trung vào sự kiện này mà không phải là nhiều kết quả khác có liên quan đến một cuộc thi đấu ba môn phối hợp) — có nghĩa là, một sự kiện có một tên (tên của cuộc thi đấu ba môn phối hợp), có thể là có một mô tả (cuộc thi đấu ba môn phối hợp kiểu nào) và một ngày tháng. Cho đến nay, JDO của tôi trông giống như Liệt kê 2:

Liệt kê 2. Một JDO của sự kiện thi đấu ba môn phối hợp đơn giản
import java.util.Date;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.IdentityType;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Triathlon {

 @Persistent
 private Date date;

 @Persistent
 private String name;

 @Persistent
 private String description;

}

Lưu trữ lâu bền dữ liệu, bất kể cơ chế nằm dưới (đó là, cơ sở dữ liệu quan hệ hoặc Big Table của Google) vẫn đòi hỏi khái niệm về khóa: một cách để bảo đảm tính độc nhất của các khía cạnh dữ liệu khác nhau để tránh những xung đột dữ liệu. Ví dụ, trong trường hợp của một cuộc thi đấu ba môn phối hợp, khóa có thể là tên của cuộc thi đấu ba môn phối hợp này. Nếu hai cuộc thi đấu ba môn phối hợp có cùng tên, thì khóa có thể là tổ hợp gồm tên và ngày tháng. Bất kể bạn chọn để biểu diễn một khoá với App Engine của Google và JDO như thế nào, bạn phải chỉ định một khóa trong đối tượng JDO của bạn thông qua chú giải @PrimaryKey. Bạn cũng có thể chọn các chiến lược để sinh ra một khóa như thế nào — hoặc do bạn làm hoặc do cơ sở hạ tầng của Google. Tôi sẽ dành việc này cho Google và làm cho nó đơn giản: khóa của đối tượng cuộc thi đấu ba môn phối hợp của tôi được biểu diễn như là một đối tượng Long Java thông thường và tôi sẽ để cho Google chọn giá trị thực tế bằng cách xác định một chiến lược giá trị. Liệt kê 3 bổ sung thêm khóa chính:

Liệt kê 3. Thêm một khóa chính cho JDO của cuộc thi đấu ba môn phối hợp
import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.IdentityType;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Triathlon {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 private Long id;

 @Persistent
 private Date date;

 @Persistent
 private String name;

 @Persistent
 private String description;

 public Triathlon(Date date, String name, String description) {
  super();
  this.date = date;
  this.name = name;
  this.description = description;
 }

 //...setters and getters left out

 public String toString() {
  return ReflectionToStringBuilder.toString(this);
 }

 public int hashCode() {
  return HashCodeBuilder.reflectionHashCode(this);
 }

 public boolean equals(Object obj) {
  return EqualsBuilder.reflectionEquals(this, obj);
 }
}

Như bạn có thể thấy trong Liệt kê 3, JDO của cuộc thi đấu ba môn phối hợp của tôi bây giờ có một khoá được cơ sở hạ tầng của Google quản lý và tôi đã thêm một vài phương thức tiêu chuẩn (toString, hashCode, và equals) chúng trợ giúp nhiều cho việc gỡ rối, ghi nhật ký và tất nhiên cả phương thức chức năng thích hợp. Thay vì tự mình viết chúng, tôi sử dụng thư viện Apache commons-lang (xem Tài nguyên). Tôi cũng đã thêm một hàm tạo (constructor) để tạo ra các đối tượng được khởi tạo đầy để dễ dàng hơn nhiều nếu so với gọi một lô phương thức setter

Tôi đã giữ cho JDO của mình đơn giản có mục đích, nhưng như bạn có thể thấy, không có nhiều thứ cho nó (đó là, tôi đã bỏ qua các mối quan hệ và bỏ qua các phương thức getter và setter cho ngắn gọn). Đơn giản là bạn mô hình hóa miền quan tâm của bạn và sau đó trang trí mô hình đó với một vài chú giải và Google sẽ lo phần còn lại.

Với một đối tượng được định nghĩa là có khả năng lưu giữ lâu bền, còn một bước cuối cùng. Để tương tác với kho lưu trữ dữ liệu nằm dưới, bạn cần phải làm việc với lớp PersistenceManager, đây là một lớp JDO tiêu chuẩn thực hiện những gì mà tên của nó ngụ ý: ghi lưu, cập nhật, lấy ra và loại bỏ các đối tượng từ một kho lưu trữ dữ liệu nằm dưới (giống như đối tượng Session của Hibernate). Lớp này được tạo ra thông qua một lớp nhà máy (PersistenceManagerFactory), nó khá phức tạp, vì thế, Google khuyến cáo tạo ra một đối tượng đơn lẻ để quản lý chỉ một cá thể của nhà máy (đối tượng ấy sẽ trả về một PersistenceManager thích hợp khi bạn cần nó). Theo đó, tôi có thể định nghĩa một đối tượng đơn lẻ đơn giản để trả về một cá thể PersistenceManager, như hiển thị trong Liệt kê 4:

Liệt kê 4. Một cá thể đơn giản để trả về một cá thể PersistenceManager
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

public class PersistenceMgr {

 private static final PersistenceManagerFactory instance =
   JDOHelper.getPersistenceManagerFactory("transactions-optional");

 private PersistenceMgr() {}

 public static PersistenceManager manufacture() {
  return instance.getPersistenceManager();
 }
}

Như bạn có thể thấy PersistenceMgr của tôi khá đơn giản. Một phương thức, manufacture, trả về một cá thể PersistenceManager từ chỉ một cá thể của một PersistenceManagerFactory. Bạn cũng sẽ nhận thấy rằng không có mã đặc thù Google nào trong Liệt kê 4 hoặc bất kỳ liệt kê nào khác sử dụng JDO — tất cả các tham chiếu đều là các lớp và các giao diện JDO tiêu chuẩn.

Hai đối tượng Java vừa mới được định nghĩa nằm trong thư mục src của dự án của tôi, và tôi đã thêm thư viện commons-lang tới thư mục war/WEB-INF/lib.

Với một JDO POJO của cuộc thi đấu ba môn phối hợp đơn giản đã định nghĩa và một đối tượng PersistenceMgr dễ sử dụng, tôi đã sẵn sàng để tiếp tục. Tất cả những thứ mà tôi cần bây giờ là một cách để nắm bắt thông tin về cuộc thi đấu ba môn phối hợp.


Nắm bắt dữ liệu qua một giao diện Web

Hầu hết các ứng dụng Web theo cùng một mẫu: nắm bắt thông tin qua các biểu mẫu (form) HTML và gửi chúng đến một nguồn tài nguyên phía máy chủ để xử lý. Chắc chắn, rất nhiều gia vị được trộn thêm ở đâu đó, nhưng mẫu này vẫn giữ nguyên không phụ thuộc vào công nghệ hoặc cơ sở hạ tầng nằm dưới. Google App Engine cũng không khác — tôi đã mã hoá nguồn tài nguyên phía máy chủ để xử lý lưu trữ dữ liệu thi đấu ba môn phối hợp. Tất cả những gì còn lại là một cách để nắm bắt được thông tin — một biểu mẫu — và một cách để buộc phía máy chủ và biểu mẫu này với nhau. Theo ngôn ngữ Model-View-Controller (MVC- Mô hình -Khung nhìn- Trình điều khiển), tôi cần một trình điều khiển, nó thường là một servlet; thay vào đó tôi sẽ sử dụng Groovlet vì tôi muốn viết mã ít hơn.

Biểu mẫu HTML của tôi rất đơn giản: tất cả những gì tôi đã làm là tạo ra một trang HTML có sử dụng mã Cascading Style Sheets (CSS-phiếu định kiểu nhiều tầng) đơn giản, được hiển thị trong Hình 1, trông giống như Web 2.0 hơn các trang HTML vào khoảng năm 1998:

Hình 1. Một biểu mẫu HTML đơn giản
Một biểu mẫu HTML đơn giản

Như bạn thấy trong Hình 1, biểu mẫu thu giữ một tên, lời mô tả và một ngày tháng. Tuy nhiên, ngày tháng không đơn giản như thế — thực sự có ba thuộc tính về ngày tháng.

Groovlet nhanh

Groovlets làm cho viết mã lệnh trình điều khiển trở thành việc ngon ơ: chúng yêu cầu mã ít hơn và tự động cung cấp các đối tượng cần thiết. Trong một Groovlet, bạn có khả năng truy cập ngầm ẩn đến các yêu cầu HTML và các đáp ứng HTML thông qua các đối tượng requestresponse tương ứng. Trong Groovlet của tôi, tôi có thể lấy ra nhanh chóng tất cả các thuộc tính của biểu mẫu HTML đã gửi lên thông qua lời gọi request.getParameter("name"), như thể hiện trong Liệt kê 5:

Liệt kê 5. Groovlets hoạt động
def triname = request.getParameter("tri_name")
def tridesc = request.getParameter("tri_description")
def month = request.getParameter("tri_month")
def day = request.getParameter("tri_day")
def year = request.getParameter("tri_year")

JDO mà tôi đã viết mã trên đây sử dụng một đối tượng Java Date (Ngày tháng); tuy nhiên, trong Liệt kê 5, tôi đang làm việc với ba thuộc tính khác biệt của Date. Vì vậy, tôi cần một đối tượng DateFormat để chuyển đổi tổ hợp tháng, ngày, năm thành đối tượng month, day, year thành đối tượng Date Java bình thường, như chỉ ra trong Liệt kê 6:

Liệt kê 6. Định dạng ngày tháng hoạt động
def formatter = new SimpleDateFormat("MM/dd/yyyy")
def tridate = formatter.parse("${month}/${day}/${year}")

Cuối cùng, với tất cả các tham số thu được từ một biểu mẫu HTML đã gửi đi, trong Liệt kê 7 tôi có thể lưu giữ lâu bền chúng vào cơ sở hạ tầng của Google qua JDO của tôi và đối tượng PersistenceMgr từ Liệt kê 4:

Liệt kê 7. JDO để lưu giữ lâu bền dễ dàng
def triathlon = new Triathlon(tridate, triname, tridesc)
def mgr = PersistenceMgr.manufacture()

try {
 mgr.makePersistent(triathlon)
} finally {
 mgr.close()
}

Vậy là xong! Dĩ nhiên nếu như nhiều trang khác được bổ sung vào ứng dụng đơn giản của tôi (ví dụ như thu giữ các kết quả của một cuộc thi đấu ba môn phối hợp cụ thể), thì tôi có lẽ sẽ chuyển tiếp hoặc chuyển hướng đến một biểu mẫu khác, sau đó biểu mẫu này sẽ nắm bắt thông tin bổ sung, giống như một trình thủ thuật. Dù sao chăng nữa, chỉ bằng một vài đoạn mã ngắn, tôi nhanh chóng sắp đặt thành một ứng dụng Web đơn giản, có thể lưu giữ lâu bền dữ liệu vào cơ sở hạ tầng của Google thông qua JDO (được mã hóa bằng Java thông thường) và một Groovlet (tất nhiên, được mã hóa theo Groovy). Việc triển khai ứng dụng rất dễ dàng, đúng như chỉ định một phiên bản trong tệp appengine-web.xml và nhấn vào nút Deploy.

Mặc dù ứng dụng Web chỉ có một biểu mẫu bắt giữ các sự kiện thi đấu ba môn phối hợp không đun sôi đại dương, phải nói như vậy, nhưng tôi đã triển khai nó tới một môi trường vô định hình, có mặt ở khắp nơi. Tôi đã không phải thực hiện một thùng chứa Web hoặc thậm chí chỉ rõ triển khai ứng dụng ở đâu. (Ổ đĩa cứng của tôi đang ở California, hoặc trên mặt trăng?). Vẻ đẹp là điều không quan trọng — Google đã chăm lo về việc này. Tất cả về việc này. Hơn nữa, đó là một sự đặt cược an toàn vì Google đã tính toán ở quy mô toàn cầu để cho ai đó xem ứng dụng ở Ấn Độ có cũng trải nghiệm tương tự như một người nào đó đang ở, nói ví dụ, Argentina.

Khi nói tất cả những điều này, bạn cần phải ghi nhớ một số điều. Cơ sở hạ tầng của Google hỗ trợ công nghệ Java, nhưng không phải hỗ trợ tất cả mọi thứ; nếu bạn còn nhớ khi J2ME xuất hiện vài năm trước đây, các hạn chế của App Engine hơi giống thế về bản chất. Nghĩa là, không phải tất cả các thư viện Java lõi và các thư viện nguồn mở có liên quan được hỗ trợ. Như tôi đã đề cập, không thể sử dụng Hibernate (chủ yếu là bởi vì bạn không có một cơ sở dữ liệu quan hệ với App Engine). Tôi cũng đã gặp một số thách thức khi sử dụng một số thư viện nguồn mở có nhúng mã hóa base64 (Google yêu cầu bạn sử dụng dịch vụ URL Fetch của mình để thay thế). App Engine là một nền tảng— bạn phải phát triển với nó và, cho đến nay, đó có thể là một đường phố một chiều.


Tương lai đã ở đây

Alan Kay, một trong những cha đẻ của lập trình hướng đối tượng, được trích dẫn rằng đã nói: "Cách tốt nhất để dự đoán tương lai là phát minh ra nó." Tôi đồng ý với Alan Kay. Bất kể những gì người khác đang giả thuyết là tương lai của công nghệ Java, tôi nghĩ rằng tương lai đã ở đây rồi.

Như bạn đã thấy trong bài viết này, Google App Engine là một nền tảng cho tương lai — đã cung cấp cho bạn trò chơi trong hộp cát (sandbox) của nó. (Hãy nhớ rằng tôi đã trình bày chỉ một vài hạt cát trong hộp cát đó, App Engine có rất nhiều tính năng). Nếu bạn muốn linh hoạt hơn (nghĩa là, bạn muốn có một cơ sở dữ liệu quan hệ và không thể sống mà không có Hibernate) nhưng lại cũng thích ý tưởng vay mượn cơ sở hạ tầng có khả năng mở rộng của người khác, đã có sẵn các sự lựa chọn thay thế. EC2 của Amazon chính xác là một máy chủ ảo trên một cơ sở hạ tầng không định hình mà bạn cũng có thể gọi đến theo yêu cầu. Bạn sẽ đọc nó trong bài viết tiếp theo về Sự phát triển Java 2.0 trong tháng tới.

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Công nghệ Java
ArticleID=452547
ArticleTitle=Phát triển Java 2.0: Chào Google App Engine
publish-date=12042009