TỔNG QUAN VỀ GOOGLE WEB TOOLKIT
Thảo luận về trình biên dịch Java thành JavaScript
GWT được hiểu rõ qua chức năng chính của nó là trình biên dịch, có nhiệm vụ chuyển mã nguồn Java thành JavaScript Tương tự như trình biện dịch Java chuyển đổi mã nguồn thành bytecode, trình biên dịch GWT sử dụng lệnh `javacom.google.gwt.dev.GWTCompiler` để biên dịch chương trình, trong đó truyền vào vị trí module và các tham số liên quan Một module GWT gồm tập hợp các lớp Java, file cấu hình đơn giản và đặc trưng bởi lớp entry point, là lớp thực thi khi dự án bắt đầu.
Trình biên dịch GWT bắt đầu quá trình biên dịch từ lớp entry point cùng với các yêu cầu cần thiết để biên dịch mã nguồn Java Khác với trình biên dịch Java tiêu chuẩn, GWT chỉ biên dịch những phần mã thực sự được sử dụng trong lớp entry point, giúp tối ưu hóa quá trình biên dịch và giảm thời gian biên dịch.
Trình biên dịch có ba cách để xuất ra mã nguồn JavaScript
Cách mặc định để làm cho mã nguồn JavaScript khó đọc là “obfuscate” (xáo trộn), giúp bảo vệ chống lại các kẻ trộm mã nguồn và giảm kích thước tệp JavaScript Phương pháp này làm mã nguồn trông giống như một đoạn đã bị mã hóa, không có khoảng cách giữa các câu lệnh và rất khó hiểu Obfuscation là rất hữu ích cho các ứng dụng lớn, đảm bảo an toàn và tối ưu hóa hiệu suất của dự án.
- Cách thứ hai là “pretty” (xinh đẹp), cách này tạo ra mã nguồn có thể đọc được Nó lại giữ mã nguồn Java gốc và cách 1 “xáo trộn”
Cách cuối cùng để dễ dàng theo dõi mã nguồn JavaScript khi so sánh với mã nguồn Java gốc là sử dụng phương pháp “chi tiết” (detailed) Phương pháp này tạo ra mã JavaScript giống như cách thứ hai, nhưng thêm tên lớp vào phần tên phương thức JavaScript, giúp tăng khả năng nhận biết và theo dõi các thành phần trong mã nguồn một cách rõ ràng và trực quan hơn.
Sử dụng JSNI thực thi mã JavaScript từ Java
JavaScript Native Interface (JSNI) giúp thực thi mã nguồn JavaScript từ Java và ngược lại, cho phép gọi trực tiếp các hàm JavaScript từ mã Java trong ứng dụng GWT JSNI được biên dịch và kết hợp chặt chẽ với mã Java, hỗ trợ tích hợp linh hoạt giữa hai ngôn ngữ Ví dụ đơn giản về JSNI là phương thức `public native int addTwoNumbers(int x, int y)`, trong đó mã JavaScript được nhúng trực tiếp để cộng hai số và trả về kết quả.
Trong Java, phương thức native được khai báo để thông báo cho trình biên dịch biết rằng phần cài đặt của nó được thực hiện bằng ngôn ngữ khác, thường là JavaScript trong các dự án GWT Khi khai báo phương thức native, người lập trình không được phép xác định mã nguồn nội bộ của phương thức đó; thay vào đó, mã nguồn JavaScript được nhúng vào trong phần chú thích nhiều dòng của phương thức Khi phương thức này được gọi, đoạn mã JavaScript bên trong chú thích sẽ được thực thi, giúp đáp ứng yêu cầu không để lộ nội dung cài đặt trong phương thức native nhưng vẫn cung cấp đoạn mã cần thiết cho trình biên dịch GWT khi thực thi.
Truy cập đến thư viện JRE emulation
Trong quá trình phát triển ứng dụng với GWT, cần xác định rõ việc sử dụng các lớp trong gói JRE, đặc biệt là liệu trình biên dịch GWT có thể hiểu và chuyển đổi chúng thành JavaScript hay không Chỉ một số lớp trong gói java.lang và java.util, như java.util.Date, được hỗ trợ trong GWT, trong khi các lớp khác như java.util.Calendar không được phép sử dụng Bảng 1.1 và bảng 1.2 cung cấp danh sách các lớp phù hợp để sử dụng trong dự án GWT, giúp các nhà phát triển tránh gặp phải lỗi khi biên dịch Cần lưu ý cẩn thận các chi tiết quan trọng, ví dụ như các giới hạn về lớp hỗ trợ liên quan đến thao tác ngày tháng, để đảm bảo ứng dụng hoạt động hiệu quả trên trình duyệt.
Bảng 1.1: Lớp java.lang.* có sẵn trong GWT
String StringBuffer System Exceptions/Errors
Bảng 1.2: Lớp java.util.* có sẵn trong GWT Classes
EmptyStackException NoSuchElementException TooManyListenersExcept -ion Interfaces
(a Mục tiêu bao gồm trong bản phát hành 1.4 của GWT)
Tìm hiểu về thư viện và widget của GWT
GWT cung cấp một lượng lớn các widget và panel để xây dựng giao diện người dùng Trong đó, widget như Button và TextBox cho phép người dùng tương tác trực tiếp, còn panel hoạt động như các thùng chứa để tổ chức các widget này một cách hợp lý Ví dụ hình 1.2 minh họa cách sử dụng các widget và panel trong việc thiết kế giao diện hiệu quả và thân thiện với người dùng.
Hình 1.2 minh họa GWT với một bộ các widget và panel giúp bạn nhanh chóng phát triển ứng dụng web đa dạng Công cụ này cho phép tạo ra các ứng dụng Internet phong phú mà không cần lo lắng về chi tiết lập trình HTML và JavaScript, giúp tiết kiệm thời gian và tăng hiệu quả phát triển.
Menubar là widget được dùng trong đỉnh của trang Tabpanel là một panel tương tác được sử dụng ở giữa trang hoạt động như một thùng chứa một widget
TextArea và một widget Button Tabpanel và Menubar đều được chứa trong một thùng chứa là AbsolutePanel mà cho phép đặt chính xác vị trí mong muốn
Các widget do GWT cung cấp tương ứng với các thành phần trong HTML như Button, TextBox, TextArea, Checkbox, RadioButton, và FormPanel Ngoài ra, GWT còn hỗ trợ hai kiểu hiển thị dữ liệu dạng bảng giống trong HTML, giúp xây dựng giao diện người dùng trực quan và dễ dàng tùy chỉnh Việc sử dụng các widget này giúp nâng cao hiệu quả phát triển ứng dụng web động và thân thiện với người dùng.
2 lớp con của HTMLTable là Grid và FlexTable.
Gọi thủ tục từ xa với GWT
Hầu hết các ứng dụng GWT cần khả năng trao đổi thông tin giữa Client và Server để hiển thị dữ liệu, đăng nhập hoặc tải dữ liệu bên ngoài Trình duyệt hiện đại tích hợp đối tượng JavaScript XMLHttpRequest, cho phép kết nối không làm mới trang như các trang HTML truyền thống Đối tượng này là nền tảng để xây dựng kỹ thuật Remote Procedure Calls (RPCs) dựa trên trình duyệt, giúp truyền dữ liệu hiệu quả giữa Client và Server.
GWT cung cấp hai công cụ chính liên quan đến đối tượng XMLHttpRequest, trong đó đầu tiên là lớp RequestBuilder, là một lớp bao ngoài nhỏ gọn nhưng ít được sử dụng hơn trong Java thông thường Công cụ thứ hai là GWT – RPC, phức tạp hơn nhưng cho phép gửi và nhận các đối tượng Java thực sự giữa Client và Server, tăng cường khả năng giao tiếp và xử lý dữ liệu trong ứng dụng web.
Công cụ xử lý XML của GWT
Trong 5 năm qua, XML đã trở thành một phần của cuộc sống hàng ngày của chúng ta cũng như các nhà phát triển ứng dụng Cấu hình máy chủ Java của chúng ta sử dụng một định dạng XML, RSS nguồn cấp dữ liệu tiêu thụ và cung cấp XML, và thường là các giao thức để chúng ta sử dụng để giao tiếp với các dịch vụ từ xa, như trong trường hợp của SOAP và XML - RPC Để làm cho nó đơn giản như có thể để giải quyết các định dạng dữ liệu trên trình duyệt của khách hàng, GWT cung cấp Document Object Model (DOM) dựa trên phân tích cú pháp XML Trình phân tích cú pháp XML dựa trên DOM sử dụng XML và tạo ra một đối tượng cây Sau đó chúng ta có thể sử dụng API DOM đi qua cây và đọc nội dung của nó
GWT có lợi thế đáng kể so với các trình duyệt hiện đại nhờ khả năng phân tích cú pháp XML và xây dựng cây DOM Việc phân tích cú pháp được thực hiện trực tiếp bởi trình duyệt, giúp tối ưu hiệu quả thực thi mã nguồn gốc của ứng dụng Nhờ đó, GWT tận dụng khả năng của trình duyệt để nâng cao hiệu suất và độ ổn định trong quá trình xử lý mã.
SO SÁNH GWT VỚI CÁC CÔNG NGHỆ KHÁC
GWT với Swing
Swing là bộ công cụ tiêu chuẩn để xây dựng các ứng dụng giao diện đồ họa trong Java, mang lại khả năng tạo ra các giao diện người dùng phức tạp và linh hoạt Khi so sánh Swing và GWT, hai khuôn khổ này có điểm tương đồng về cách viết mã, giúp lập trình viên dễ dàng thích nghi khi chuyển đổi giữa chúng Ví dụ về Swing minh họa cho sự đa dạng trong các thành phần và khả năng tùy biến của thư viện này.
Here's an example of Java code creating a simple GUI with a JTextField and JButton When the button is clicked, the text in the JTextField updates to display "clicked." This demonstrates how to add an ActionListener to a JButton to handle user interactions and modify components dynamically Utilizing these components and event handling techniques is essential for developing interactive Java Swing applications.
} }); final JFrame rootPanel = new JFrame();
Panel main = new Panel(); rootPanel.getContentPane().add(main); main.add(text); main.add(button); rootPanel.setVisible(true); rootPanel.pack();
Mã Swing này rất giống với ví dụ tham khảo GWT, gần như không có sự khác biệt đáng kể, chỉ khác ở cách đặt tên các thành phần như sử dụng ActionListener thay vì ClickListener trong GWT Đối với các nhà phát triển Swing, có những điểm khác biệt quan trọng so với GWT, đặc biệt là về mô hình kiến trúc Thứ nhất, mã của GWT không tuân theo mô hình Model View Controller (MVC) và không sử dụng mô hình đối tượng có thể chia sẻ giữa các thành phần để đảm bảo đồng bộ Thứ hai, GWT không quản lý bố cục bằng các phương pháp truyền thống, thay vào đó sử dụng các panel để xây dựng phong cách bố trí giao diện người dùng.
HorizontalPanel trong GWT cho phép sắp xếp các thành phần con theo chiều trái sang phải trên cùng một trang, phù hợp cho việc bố trí các yếu tố theo hàng ngang Trong khi đó, DockPanel cung cấp khả năng thêm các widget vào các khu vực cụ thể của giao diện, tương tự như BorderLayout của Swing, giúp tạo ra bố cục linh hoạt và rõ ràng hơn Cả hai phương pháp này đều hỗ trợ xây dựng giao diện người dùng trực quan và dễ quản lý trong ứng dụng GWT.
Các sự khác biệt này khá dễ hiểu và GWT là một môi trường phát triển phù hợp cho các nhà phát triển Swing Tiếp theo, chúng ta sẽ xem xét về Echo2, một framework cho phép xây dựng ứng dụng web theo cách tương tự như GWT nhưng sử dụng một cách tiếp cận khác nhau, giúp các nhà phát triển dễ dàng phát triển và tối ưu hóa ứng dụng của mình.
GWT với Echo2
Echo2 là một bộ công cụ web phổ biến, tương tự như GWT, được sử dụng để tạo giao diện người dùng một cách hiệu quả Bạn có thể tận dụng API để tạo các thành phần và sau đó dễ dàng thêm chúng vào màn hình, giúp phát triển giao diện linh hoạt và tùy biến Ví dụ 2.3 minh họa phiên bản Echo2 của một ví dụ tham khảo GWT, cho thấy hai phiên bản này trông gần như giống hệt nhau, hỗ trợ người dùng trong việc lựa chọn công cụ phù hợp cho dự án của mình.
In Echo2, to create an interactive button that updates a text field upon clicking, you can initialize a TextField with default text and set up a Button with an action listener For example, define a TextField with `final TextField text = new TextField();` and set its initial content using `text.setText("text box");` Create a Button labeled "Click Me" using `final Button button = new Button();` and assign an action listener to it When the button is clicked, the event handler updates the TextField's content to "clicked" with `text.setText("clicked");`, enabling dynamic user interaction within your Echo2 application.
Window window = new Window(); window.setContent(new ContentPane());
Row main = new Row(); window.getContent().add(main); main.add(text); main.add(button);
Dù cả hai khuôn khổ sử dụng API tương tự, chúng hoạt động trong các môi trường hoàn toàn khác nhau Ứng dụng viết cho Echo2 chạy trên máy chủ, trong khi GWT biên dịch mã Java sang JavaScript để chạy trên trình duyệt Khi phát triển với Echo2, mã nguồn Java được biên dịch thành các tập tin lớp để chạy trên máy chủ, điều này có nghĩa là các sự kiện phía khách hàng có thể cần xử lý trên máy chủ.
Giao diện xây dựng với Echo2 giúp các máy chủ hoạt động hiệu quả hơn bằng cách chỉ gửi những phần JavaScript cần thiết cho trình duyệt của người dùng Điều này tối ưu hóa hiệu suất và giảm tải cho trình duyệt, đồng thời nâng cao trải nghiệm người dùng Echo2 tích hợp chặt chẽ với máy chủ ứng dụng Java, vì vậy việc lưu trữ và vận hành ứng dụng trở nên dễ dàng và linh hoạt hơn Tóm lại, Echo2 là giải pháp lý tưởng để phát triển giao diện web hiệu quả, tối ưu hóa hoạt động của máy chủ và nâng cao trải nghiệm người dùng.
GWT với JavaServer Faces
JavaServer Faces (JSF) là một framework web cho các ứng dụng dựa trên Java, giúp quản lý các mô hình trên máy chủ một cách hiệu quả Nó sử dụng tập hợp các thư viện thẻ có thể tích hợp với trang JSP để tham khảo thuộc tính của mô hình, từ đó dễ dàng xây dựng giao diện người dùng Trong các triển khai tiêu chuẩn, tất cả các công đoạn xử lý đều thực hiện trên máy chủ và trang web được tải lại cho mỗi giao dịch, đảm bảo tính đồng bộ và chính xác của dữ liệu.
Bước đầu tiên để tạo ứng dụng JSF là xây dựng lớp mô hình đại diện, như ví dụ 2.4, trong đó mô hình đơn giản chỉ chứa một biến văn bản Theo tiêu chuẩn JavaBean, bạn cần định nghĩa sở hữu tư nhân cho biến này và cung cấp phương thức getter và setter để truy cập và cập nhật giá trị Ngoài ra, bạn cần thêm phương thức `changeText()`, sẽ được kích hoạt khi nút lệnh trong giao diện người dùng được nhấn.
Ví dụ 2.4: package org.gwtbook; public class SampleBean { private String text = "text box"; public String getText () { return text;
} public void setText (String text) { this.text = text;
} public void changeText () { this.text = "clicked";
Tiếp theo, bạn cần đăng ký lớp này như một bean được quản lý trong các tệp cấu hình JSF (xem ví dụ 2.5) để tích hợp vào ứng dụng Hãy cung cấp tên cho bean, ví dụ như `sampleBean`, để dễ dàng tham chiếu trong mã JSP Việc đăng ký và đặt tên cho bean giúp quản lý tốt hơn và đảm bảo khả năng truy cập trong các trang web JSF.
Ví dụ 2.5: Một đoạn của file cấu hình JSF định nghĩa một bean được quản lý
sampleBean
org.gwtbook.SampleBean request
Trang JSP trong ví dụ trên trông giống như một trang JSP tiêu chuẩn, sử dụng hai thư viện thẻ JSF để xác định và điều khiển các thành phần trên trang Các giá trị trong thẻ inputText được tham khảo từ dữ liệu quản lý của bạn thông qua ngôn ngữ biểu hiện JSF, giúp liên kết dữ liệu một cách linh hoạt và dễ dàng quản lý Trong thẻ actionButton, bạn cũng thấy sự xuất hiện của các thành phần tương tự, thể hiện khả năng thao tác và xử lý sự kiện một cách trực quan trên giao diện người dùng.
JSF cung cấp rất ít hỗ trợ cho các chức năng phía máy khách, gây hạn chế trong xây dựng và tái sử dụng thành phần phía client Mặc dù JSF có thể tạo và tùy chỉnh thành phần phía máy khách bằng cách sử dụng JavaScript, các thành phần tùy chỉnh có giá trị sử dụng lại ít hơn so với các framework khác Do tích hợp phía khách hàng, JSF cạnh tranh với GWT, tuy nhiên, vẫn còn nhiều tiềm năng để tích hợp hai công nghệ này hiệu quả hơn trong phát triển ứng dụng web.
GWT với Ruby on Rails
Ruby on Rails là một khuôn khổ phát triển web nhanh chóng dựa trên ngôn ngữ Ruby, tối ưu cho việc xử lý tự động các công việc phía máy chủ Nó hỗ trợ tích hợp Ajax, cho phép gửi dữ liệu đến máy chủ dựa trên hành động của người dùng và cập nhật nội dung trang web một cách linh hoạt Tuy nhiên, Rails không phù hợp cho các ứng dụng đòi hỏi tương tác phức tạp giữa khách hàng và máy chủ.
GWT là nền tảng phát triển giao diện người dùng trung tâm, cho phép xây dựng và hiển thị các widget bằng Java Với GWT, bạn có thể viết mã Java xử lý để bắt sự kiện người dùng và kích hoạt các hành động phù hợp Nó có khả năng giao tiếp linh hoạt với máy chủ theo nhu cầu, thúc đẩy bởi các tương tác của người dùng để cập nhật dữ liệu hoặc thực hiện tác vụ GWT còn cho phép biên dịch mã Java sang JavaScript, giúp các ứng dụng của bạn chạy mượt mà trong trình duyệt của người dùng Tại phía máy chủ, GWT mainly cung cấp cơ chế serialize và deserialize đối tượng Java, giúp truyền dữ liệu giữa client và server một cách hiệu quả, mà không tham gia vào các khía cạnh xử lý khác của máy chủ.
XÂY DỤNG GIAO DIỆN NGƯỜI DÙNG VỚI GWT
Làm việc với Widget
Widget là một trong bốn khối xây dựng cơ bản của ứng dụng GWT, bao gồm bảng, sự kiện và máy chủ truyền thông như RPC, JSON, xử lý XML và AJAX với XMLHttpRequest Khi người dùng chạy ứng dụng GWT, họ tương tác với các widget đã được bố trí trong bảng và phản hồi theo các sự kiện Widget giống như các nút trên bộ điều khiển từ xa, là các thành phần giao diện người dùng cho phép tương tác GWT cung cấp miễn phí nhiều loại widget phổ biến như Button, TextBox, CheckBox và TextArea để xây dựng giao diện người dùng linh hoạt và hiệu quả.
TextArea a Sử dụng Widget như một đối tượng Java
Mục đích của GWT là phát triển các ứng dụng web phong phú bằng Java, với trình biên dịch GWT chuyển đổi mã thành HTML và JavaScript phù hợp cho nhiều trình duyệt khác nhau Để đảm bảo tương thích và hoạt động trơn tru trên các trình duyệt đa dạng, GWT sử dụng các widget để đại diện cho các đối tượng trình duyệt khác nhau trong chương trình Java của mình.
Trong một chương trình GWT, bạn muốn sử dụng đối tượng Java Button để tạo các giao diện người dùng tương tác Đối tượng Button này cho phép bạn dễ dàng thiết lập văn bản rõ ràng và xử lý các sự kiện nhấn nút, giúp xây dựng các thành phần UI theo ý muốn Bạn có thể tùy chỉnh tất cả các widget như đối tượng Java với các phương thức và sự kiện phù hợp, tạo ra trải nghiệm người dùng linh hoạt và trực quan trên trình duyệt.
Khi sử dụng lập trình GWT, cần xem xét các widget phản ánh cấu trúc tự nhiên của đối tượng Java Nút được tạo ra bằng cách xây dựng lớp Button trong GWT Java, giúp đảm bảo tính nhất quán giữa giao diện người dùng và mã nguồn phía sau Việc lựa chọn widget phù hợp trong GWT là yếu tố quan trọng để tối ưu hóa hiệu suất và khả năng mở rộng của ứng dụng web.
Button theButton = new Button("Click Me");
Mã này tạo ra một nút mới cho phép người dùng thực hiện các lớp phương thức khác nhau, phù hợp với nhiều mục đích sử dụng Các nhiệm vụ trong bảng 3.1 đề cập đến những hoạt động điển hình mà bạn có thể thực hiện trên một widget nút GWT, giúp tùy chỉnh chức năng của nút theo yêu cầu của dự án.
Bảng 3.1: Chức năng mà kết quả từ việc áp dụng một số lớp phương thức Button cho các đối tượng Java Button
Code Mô tả theButton.setStyleName("buttonStyle");
Establish a cascading style sheet (CSS) by defining class names for buttons to ensure consistent styling across your web document Each corresponding CSS entry must be linked to the web document and should begin with a period (e.g., buttonStyle { }) to denote a class selector This approach facilitates effective customization of button appearances and maintains organized, maintainable code For instance, you can add a click listener to a button using code like: theButton.addClickListener(new ClickListener() { public void onClick(Widget sender) { } }), enabling interactive functionality alongside your styled elements.
Thêm một ClickListener vào nút để xử lý sự kiện nhấn chuột, giúp phản hồi người dùng khi họ tương tác với nút Khi nhấn vào nút, phương thức onClick() trong ClickListener sẽ được thực thi, cho phép thay đổi nội dung hoặc trạng thái của nút Ví dụ, bạn có thể sử dụng theButton.setText("Go on, click me") để cập nhật văn bản hiển thị trên nút, hoặc theButton.setVisible(false) để ẩn nút khỏi giao diện người dùng Việc này giúp quản lý các phần tử giao diện như các phần tử DOM, từ đó kiểm soát hành vi của widget hiệu quả hơn trên trang web.
Trong Java, bạn có thể xây dựng các ứng dụng GWT linh hoạt bằng cách sử dụng nhiều widget khác nhau và các phương thức liên quan để phát triển các chức năng đa dạng Tuy nhiên, để hiển thị các đối tượng Java trên trình duyệt web, cần có một ứng dụng Ajax, vì Java không thể trực tiếp hiển thị các đối tượng này trong môi trường trình duyệt Vì vậy, DOM đóng vai trò quan trọng trong việc thay thế và đại diện cho các widget trong quá trình hiển thị và tương tác của ứng dụng GWT trên web.
Document Object Model (DOM) là cách thể hiện các trang web mà bạn nhìn thấy, cho phép truy cập và thay đổi nội dung trang một cách linh hoạt Bạn có thể sử dụng nhiều ngôn ngữ lập trình như JavaScript hoặc Java để thao tác với DOM, và các thay đổi này thường được hiển thị ngay lập tức trên trình duyệt Các thao tác trên DOM bao gồm thêm hoặc loại bỏ các yếu tố, chỉnh sửa khả năng hiển thị của các phần tử, cũng như thay đổi vị trí của chúng để tùy chỉnh giao diện web Trong trường hợp của GWT, các thao tác này được thực hiện thông qua JavaScript trong mã biên dịch, mặc dù trong lập trình chúng ta vẫn sử dụng Java để tương tác với DOM.
Tất cả các widget GWT đều có một đại diện DOM thay thế được xây dựng song song với các đối tượng Java, giúp kết nối trực tiếp giữa mã Java và giao diện người dùng Phép khởi tạo Java chịu trách nhiệm tạo ra đại diện DOM, như trong ví dụ của lớp Button với constructor gọi phương thức tạo nút DOM và điều chỉnh kiểu dáng cũng như lớp CSS phù hợp Việc xây dựng này đảm bảo tính nhất quán giữa mã Java và cấu trúc giao diện người dùng, tối ưu hóa hiệu suất và khả năng mở rộng của các widget trong GWT.
Gọi đến DOM.createButton() tạo ra phần tử DOM thông qua lớp
Trong GWT DOM, phương thức setElement() được sử dụng trong các lớp cha mẹ để thiết lập các lớp Java của widget DOM đại diện cho phần tử HTML, chẳng hạn như thẻ Nhờ vào phương thức này, developers có thể kết nối và quản lý các yếu tố DOM bằng Java thông qua việc sử dụng phương thức getElement() Điều này giúp tạo ra sự liên kết chặt chẽ giữa mã Java và cấu trúc HTML, tối ưu hóa việc thao tác phần tử trên giao diện người dùng.
GWT phân phối tiêu chuẩn đi kèm với một bộ các widget đa dạng để sử dụng trong các ứng dụng, bao gồm các loại phổ biến như nút và văn bản Tuy nhiên, một số widget mà bạn mong đợi như thanh tiến trình và thanh trượt lại không có sẵn trong bộ tiêu chuẩn, mặc dù bạn hoàn toàn có thể xây dựng chúng theo nhu cầu.
Trong các thiết lập của widget, các nhà thiết kế của GWT đã xây dựng một hệ thống phân cấp mạnh mẽ dựa trên các lớp Java để đảm bảo tính nhất quán giữa các widget như TextBox, TextArea và PasswordTextBox GWT nhận diện rõ ràng về cấu trúc này và tổ chức các widget thừa kế từ lớp cha chung là TextBoxBase, giúp duy trì tính linh hoạt và đồng nhất trong quá trình phát triển giao diện người dùng Bạn có thể xem hình 3.1 để hình dung rõ hơn về cấu trúc phân cấp này.
Trong hệ thống phân cấp widget, tất cả các widget cuối cùng kế thừa từ lớp UIObject, trong đó phương thức setElement() đóng vai trò quan trọng trong việc thiết lập liên kết vật lý giữa đối tượng Java của widget và DOM views Lớp con của UIObject phải gọi phương thức này đầu tiên trước các phương thức khác để đảm bảo liên kết đến yếu tố trình duyệt được thiết lập chính xác Việc sử dụng phương thức setElement() đúng cách là bước quan trọng để đảm bảo tính đồng bộ giữa mã Java và giao diện người dùng dựa trên DOM.
Tất cả các widget GWT kế thừa từ lớp UIObject, giúp cung cấp các phương thức và thuộc tính chung như thiết lập kích thước, quản lý tầm nhìn và tên phong cách Lớp UIObject còn tạo liên kết giữa các cơ quan đại diện Java và DOM, đảm bảo hoạt động trơn tru của các widget trong ứng dụng.
Hình 3.1: GWT widget - Hệ thống phân cấp lớp
Làm việc với Panel
Panels là các khối xây dựng chính của ứng dụng GWT, giúp xác định cấu trúc và chức năng của giao diện người dùng Chúng cho phép bạn dễ dàng định vị các widget theo vị trí phù hợp để thực hiện các chức năng của ứng dụng Việc sử dụng Panels tối ưu hóa quá trình phát triển và nâng cao trải nghiệm người dùng trong ứng dụng GWT.
RootPanel là giao diện trực tiếp truy cập vào trang web hiện tại của trình duyệt, là một trường hợp đặc biệt khi nắm bắt toàn bộ nội dung trình duyệt Các bảng khác trong giao diện không có kiến thức về trình duyệt cho đến khi được thêm vào thông qua các phương thức trong lớp RootPanel, giúp quản lý hiển thị một cách hiệu quả Ngoài RootPanel, các panel khác đóng vai trò như các thùng chứa cho widget, cung cấp cấu trúc cần thiết để tổ chức và xây dựng ứng dụng của bạn một cách hợp lý Sử dụng Panel như một đối tượng Java giúp dễ dàng tùy biến, quản lý các phần tử giao diện trong ứng dụng.
GWT cung cấp nhiều loại panel đa dạng, từ FlowPanel đơn giản, nơi các thành phần được bố trí theo hàng hoặc cột, đến các bảng phức tạp hơn như DeckPanel, cho phép tổ chức các widget nhỏ thành từng trang riêng biệt DeckPanel hoạt động giống như một bộ bài, chỉ hiển thị một widget tại một thời điểm, giúp quản lý giao diện người dùng một cách linh hoạt và hiệu quả.
Khi tạo ra một FlowPanel, một bảng điều khiển cho phép thêm bất kỳ widget nào với kích thước phù hợp, bạn cần sử dụng mã Java phù hợp để thiết lập và quản lý các thành phần trong bảng điều khiển Điều này giúp tối ưu hóa khả năng tùy biến và dễ dàng mở rộng giao diện người dùng một cách linh hoạt và hiệu quả.
Mã này tạo ra một đối tượng FlowPanel Java mới, cho phép bạn thực hiện một số phương thức của lớp Các phương thức này được liệt kê rõ ràng trong bảng, giúp người dùng hiểu rõ các chức năng và cách sử dụng của từng phương thức để tối ưu hóa giao diện người dùng Việc sử dụng FlowPanel giúp dễ dàng tổ chức và quản lý các thành phần trong giao diện Java, nâng cao hiệu quả thiết kế và trải nghiệm người dùng.
Bảng 3.2: Áp dụng một số phương thức lớp Java Panel đối tượng FlowPanel Java
Code Mô tả theFlowPanel.setStyleName("buttonStyle");
Thiết lập Style Sheet Cascading
Phong cách CSS cho FlowPanel giúp định dạng các thành phần trong giao diện người dùng một cách rõ ràng và nhất quán Một mục tương ứng trong CSS được liên kết trực tiếp với tài liệu web để đảm bảo kiểu dáng hiển thị chính xác Để thêm nội dung vào FlowPanel, có thể sử dụng lệnh `theFlowPanel.add(new Label("Test"));`, giúp bổ sung widget Label mới một cách dễ dàng và hiệu quả Việc sử dụng CSS trong FlowPanel tối ưu hóa trải nghiệm người dùng và nâng cao tính thẩm mỹ của trang web.
Lấy một đối tượng Java cho phép bạn lặp lại trên tất cả các widget đã được thêm vào trong FlowPanel Đối tượng Java của các panel giúp điều chỉnh các bảng điều khiển như một đối tượng Java thuần khiết, tạo điều kiện cho việc kiểm soát linh hoạt hơn Mặc dù phương thức add() cho phép các bảng điều khiển hoạt động và hiển thị trên trình duyệt, nó không thể giúp bạn hiểu rõ cách xử lý bên trong của chúng Để có cái nhìn toàn diện hơn, chúng ta cần xem xét các bảng điều khiển như các phần tử DOM, giúp hiểu rõ hơn về cách chúng hoạt động từ góc nhìn của trình duyệt.
Các phần tử DOM xác định các panel hiển thị trong trình duyệt web, giúp quản lý giao diện người dùng một cách hiệu quả Khi tạo bảng điều khiển bằng Java, các lớp xây dựng chịu trách nhiệm tạo ra các phần tử DOM cần thiết để hiển thị đúng nội dung, như ví dụ từ lớp FlowPanel với phương thức khởi tạo public FlowPanel() { setElement(DOM.createDiv()); } Điều này đảm bảo cấu trúc HTML phù hợp và dễ dàng kiểm soát các thành phần giao diện trong ứng dụng web của bạn.
Khi tạo một đối tượng Java FlowPanel, đồng nghĩa với việc bạn đang tạo ra một phần tử div trong DOM Nếu bạn kiểm tra trực tiếp các phần tử DOM của FlowPanel, sẽ thấy chúng phản ánh cấu trúc của div này, giúp hiểu rõ hơn về cách các thành phần giao diện được xây dựng trong web.
Trong hệ thống GWT, RootPanel đóng vai trò là bảng điều khiển liên kết các ứng dụng của cửa sổ trình duyệt Nó cung cấp tài liệu tham khảo đặc biệt đối với các yếu tố DOM trên trang, thay vì là một bảng điều khiển chính riêng biệt Có hai cách sử dụng đối tượng RootPanel: một là vượt qua tên DOM đã biết, như RootPanel.get("MyDomArea"), để nhận về tham chiếu đến phần tử DOM cụ thể; hai là gọi RootPanel.get() mà không có tham số để lấy tham chiếu đến yếu tố Body của trang.
GWT phân phối tiêu chuẩn đi kèm với một loạt các panel đa dạng, cung cấp các chi tiết phong phú về hệ thống Các panel này được phân thành năm nhánh chính, tương ứng với các sự cố khác nhau trong hệ thống phân cấp lớp, như thể hiện trong hình 3.4 Việc phân chia này giúp cung cấp thông tin rõ ràng và toàn diện về các trạng thái và lỗi của hệ thống.
Các panel đơn giản dựa trên phần tử div và thường chỉ chứa một widget, tạo thành các khối nhỏ gọn, dễ quản lý Mặc dù thường chỉ chứa một widget, nhưng trong thực tế, một widget có thể là một bảng chứa các widget hoặc panel khác, cho phép xây dựng giao diện phức hợp và linh hoạt hơn Việc sử dụng các panel đơn giản giúp tối ưu hóa cấu trúc mã nguồn và nâng cao trải nghiệm người dùng trong thiết kế giao diện.
Panel phức tạp cho phép chứa nhiều widget khác nhau và thường dựa trên các phần tử HTML như div hoặc table Tuy nhiên, khi sử dụng các widget, bạn không nên dựa vào cấu trúc nội bộ của chúng vì cấu trúc này có thể thay đổi trong tương lai, ảnh hưởng đến khả năng tùy biến và duy trì của giao diện.
- HTML table panels: Những panel dựa trên các bảng HTML và được dự kiến sẽ tiến hành như thế
- Composite panels: Panel tổng hợp là một sự kết hợp của các panel khác với nhau để cung cấp một số chức năng mới
- Split panels: mới xuất hiện trong GWT 1.4 là gia đình SplitPanel, cung cấp một thanh trượt giữa hai widget mà cho phép bạn được thay đổi kích cỡ
Trong hệ thống phân cấp của GWT, tất cả các Panel đều thuộc phân lớp trừu tượng của GWT, giúp tổ chức và quản lý giao diện người dùng hiệu quả Lớp Panel là lớp con của Widget và cũng kế thừa từ UIObject, mang đến khả năng tùy biến cao cho các thành phần giao diện Một điểm nổi bật của Panel là khả năng tạo ra các Panel sự kiện chìm, cho phép ghi đè phương thức onBrowserEvent() để xử lý các sự kiện người dùng một cách linh hoạt và tối ưu hơn trong các ứng dụng web.
Hình 3.4: Hệ thống phân cấp lớp các panel được cung cấp với khuôn khổ
GWT 1.3, hiển thị các loại khác nhau của các panel có sẵn a Tương tác với các Panel đơn giản
SimplePanel giới hạn số lượng widget có thể thêm vào một panel để tối ưu hóa hiệu suất Lớp SimplePanel mở rộng từ lớp Panel, kế thừa các tính năng cơ bản, đồng thời bổ sung khả năng kiểm soát số lượng widget tối đa Với việc tách nhỏ ra, SimplePanel giúp quản lý hiệu quả hơn các thành phần giao diện người dùng, đảm bảo sự mạch lạc và dễ bảo trì Các biến trong lớp SimplePanel đảm nhận vai trò lưu trữ thông tin về các widget, giúp quá trình xử lý và hiển thị trở nên linh hoạt hơn.
Xem năm tấm SimplePanel sau o PopupPanel o DialogBox o FormPanel o FocusPanel o ScrollPanel
Một PopupPanel "pops” lên trên các tiện ích khác trên trang của bạn và bạn có thể sử dụng nó, ví dụ, để thực hiện chức năng tooltip
Xử lý sự kiện
3.3.1 Khám phá các sự kiện
Xử lý sự kiện trong các ứng dụng web giúp người dùng dễ dàng tương tác và truy cập các chức năng chính của ứng dụng Các sự kiện có thể xảy ra khi người dùng nhấp vào nút, kéo thả thành phần, hoặc thay đổi giá trị, mang lại trải nghiệm tương tác mượt mà GWT hỗ trợ toàn diện các sự kiện trình duyệt phổ biến như trong bảng 3.3, giúp phát triển ứng dụng web linh hoạt và dễ quản lý.
Bảng 3.3: Trình duyệt các sự kiện mà một ứng dụng GWT có thể xử lý, cùng với giá trị nội bộ GWT có thể sẽ được giao
Nút chuột trái được nhấp (BUTTON_LEFT) là một hành động phổ biến khi người dùng tương tác với trang web, giúp kích hoạt các chức năng quan trọng Nút chuột giữa (BUTTON_MIDDLE) thường được sử dụng để mở liên kết trong tab mới hoặc thực hiện các thao tác đặc biệt Nút chuột phải (BUTTON_RIGHT) cho phép mở menu ngữ cảnh hoặc truy cập các tùy chọn bổ sung Yếu tố không tập trung vào bàn phím (ONBLUR) xảy ra khi trường nhập liệu hoặc phần tử giao diện mất tiêu điểm, ảnh hưởng đến trải nghiệm người dùng Giá trị của một yếu tố đầu vào đã thay đổi (ONCHANGE) giúp cập nhật dữ liệu tự động, nâng cao tính tương tác của trang web Người dùng nhấp vào một phần tử (ONCLICK) để kích hoạt các hành động như gửi biểu mẫu hoặc chuyển hướng.
ONDBLCLICK Người dùng nhấp đúp vào một phần tử ONERROR
Một lỗi JavaScript xảy ra (sự kiện này lỗi là thường xuyên nhất, tìm thấy khi tải một hình ảnh không thành công)
ONFOCUS Ngược lại của sự kiện onBlur: Một yếu tố được tập trung bàn phím
ONKEYDOWN Người sử dụng nhấn một phím
ONKEYPRESS Một nhân vật được tạo ra từ việc bấm phím (hoặc trực tiếp hoặc thông qua autorepeat)
ONKEYUP Người sử dụng phát hành một khóa ONLOAD Một yếu tố (thông thường là một IMG) hoàn tất tải
ONLOSECAPTURE Một yếu tố có bắt chuột khi nó bị mất
ONMOUSEDOWN Người dùng nhấp chuột trên một phần tử
ONMOUSEMOVE Chuột di chuyển trong khu vực của một yếu tố
ONMOUSEOUT Chuột di chuyển ra khỏi khu vực của một yếu tố
ONMOUSEOVER Chuột di chuyển vào khu vực của một yếu tố ONMOUSEUP Người sử dụng phát hành chuột trên một phần tử
ONSCROLL Một yếu tố cuộn bù đắp thay đổi
FOCUSEVENTS Đây là một bitmask bao gồm cả tập trung và các sự kiện mờ OnFocus / OnBlur
KEYEVENTS Đây là một bitmask bao gồm xuống, lên, và bấm các sự kiện bàn phím OnKeyDown / OnKeyPress / Onkeyup
MOUSEEVENTS là một bitmask bao gồm các sự kiện chuột như nhấn xuống, thả ra, di chuyển, di chuyển lên trên và ra khỏi đối tượng Tuy nhiên, nó không bao gồm các sự kiện nhấp chuột hoặc nhấp đôi chuột, giúp các nhà phát triển dễ dàng xác định các hành động của người dùng trên giao diện Việc hiểu rõ MOUSEEVENTS hỗ trợ tối ưu trong việc xử lý sự kiện chuột một cách chính xác và hiệu quả trong các ứng dụng phần mềm.
Tìm hiểu về các mô hình sự kiện
Một trong những điểm đặc trưng của ứng dụng GWT là đăng ký một hàm xử lý sự kiện toàn cầu duy nhất tại cấp độ tài liệu của trình duyệt Quá trình này được thực hiện thông qua phương thức init() của lớp DOM, với hai hiện thực khác nhau cho trình duyệt IE và các trình duyệt còn lại mà GWT hỗ trợ.
Khi tạo một widget, bạn cần sử dụng phương thức sinkEvents() để cho phép widget lắng nghe các sự kiện phù hợp Điều này giúp widget xử lý các sự kiện đặc biệt và tương tác hiệu quả hơn, cải thiện trải nghiệm người dùng trên giao diện của bạn.
Để xử lý các sự kiện bị đánh chìm trong quá trình cung cấp dữ liệu, bạn cần ghi đè phương thức onBrowserEvent() để phù hợp Việc này giúp đảm bảo các sự kiện được quản lý chính xác, cải thiện khả năng tương tác của giao diện người dùng Ghi đè onBrowserEvent() là bước quan trọng trong việc tùy chỉnh phản hồi cho các sự kiện trình duyệt trong ứng dụng của bạn, nâng cao hiệu quả xử lý và trải nghiệm người dùng.
- Thêm một widget vào một trang
Một widget hoặc panel sẽ không bắt đầu lắng nghe các sự kiện cho đến khi nó được thêm vào cấu trúc DOM của trang web Điều này quan trọng để nhớ, đặc biệt nếu bạn quên rằng có hai đối tượng JavaScript và DOM liên quan đến widget hoặc panel đó Việc hiểu rõ thời điểm widget bắt đầu lắng nghe sự kiện giúp đảm bảo chức năng hoạt động chính xác và tránh lỗi không lường trước trong quá trình phát triển ứng dụng web.
GWT tự động quản lý cơ chế cho bạn, chỉ cần thêm widget hoặc panel trực tiếp vào trang trình duyệt bằng phương thức RootPanel.get().add(widget hoặc panel) hoặc chèn vào bảng khác Khi một thành phần được thêm vào trang, phương thức onAttach() của nó sẽ được gọi để đăng ký như một trình nghe sự kiện trong hệ thống phân cấp DOM Các widget sau đó sẽ lắng nghe và sẵn sàng tiếp nhận các sự kiện, đảm bảo tính tương tác tối ưu trên giao diện người dùng.
Trong trình duyệt Internet Explorer, các sự kiện được xử lý theo cơ chế đặc thù, xảy ra khi người dùng nhấn vào các yếu tố được click và được quản lý trực tiếp trong trình duyệt Trong các trình duyệt khác, quy trình xử lý sự kiện thường diễn ra ở cấp độ tài liệu, giúp đảm bảo khả năng tương thích và hiệu suất hoạt động tối ưu Việc hiểu rõ cách các trình duyệt xử lý sự kiện là rất quan trọng để tối ưu hóa trải nghiệm người dùng và đảm bảo ứng dụng web hoạt động mượt mà.
Sau khi sự kiện này được chụp, JavaScript gọi phương thức
Phương thức $wnd dispatchEvent() được tạo ra trong hàm init() của DOM để xử lý sự kiện Nó có nhiệm vụ tìm kiếm và chọn lọc trình xử lý phù hợp nhất để xử lý các sự kiện đã bắt được, đảm bảo phản hồi chính xác và hiệu quả trong quá trình xử lý sự kiện trên trang web.
- Kiểm tra một sự kiện
Khi một sự kiện được bắt, ứng dụng GWT kiểm tra xem các yếu tố liên quan đến sự kiện này đã xảy ra trên người dùng hay chưa Nếu có, ứng dụng sẽ gọi phương thức dispatchEvent() trong lớp DOM để xử lý sự kiện Quá trình này bao gồm đi qua các phần tử và tham chiếu đến các EventListener đang lắng nghe trên các phần tử đó Điều này giúp đảm bảo rằng các phản hồi của ứng dụng diễn ra đúng theo quy trình xử lý sự kiện trong môi trường GWT.
- Xử lý một sự kiện
Xử lý các sự kiện trong lập trình web được thực hiện thông qua phương thức onBrowserEvent() Trong quá trình này, bạn có thể tùy chỉnh hành động của sự kiện bằng cách sử dụng các phương thức như DOM.eventCancelBubble() để hủy bong bóng sự kiện và ngăn các widget khác nhận diện sự kiện đó Ngoài ra, bạn còn có thể ngăn trình duyệt thực hiện hành động mặc định của sự kiện bằng cách gọi DOM.eventPreventDefault(), giúp kiểm soát tốt hơn quá trình xử lý sự kiện trên trang web.
Bạn có thể dễ dàng tích hợp các sự kiện liên tục trở lại vào mã của mình bằng cách sử dụng các mô hình thiết lập Listener để quản lý sự kiện hiệu quả Việc này giúp đảm bảo mã của bạn luôn linh hoạt và dễ mở rộng, tối ưu hóa trải nghiệm người dùng và tăng hiệu quả xử lý sự kiện.
3.3.2 Lắng nghe các sự kiện
Để một widget có thể xử lý các sự kiện của chính nó, nó cần đăng ký bằng cách "đánh chìm" sự kiện này, quá trình có thể thực hiện rõ ràng hoặc ngầm qua kế thừa Việc này giúp widget kiểm soát và phản hồi đúng các sự kiện xảy ra, từ đó nâng cao khả năng tương tác và tùy biến trong lập trình giao diện người dùng.
Một cách để một widget đăng ký sự kiện là sử dụng phương thức sinkEvents(), cho phép bạn chỉ định loại sự kiện mà widget quan tâm, qua đó đăng ký phương thức wnd. dispatchEvent() để xử lý các sự kiện này Khi làm như vậy, widget sẽ xử lý tất cả các sự kiện của trình duyệt liên quan, đồng thời cập nhật đại diện phần tử DOM của nó để phản hồi các sự kiện Ví dụ trong bảng điều khiển, Panel Dashboard có thể xử lý các sự kiện nhấp đúp để thu nhỏ hoặc mở lại bảng điều khiển; khi người dùng nhấp vào thùng chứa, bảng sẽ thu nhỏ chỉ còn hiển thị tiêu đề, và nhấp đúp lần nữa để khôi phục toàn bộ nội dung bằng cách thao tác loại bỏ các widget hiển thị và thay thế bằng hình ảnh 1 pixel.
CÔNG NGHỆ GIAO TIẾP GIỮA CLIENT – SERVER
Giao tiếp với GWT – RPC
Khi xây dựng ứng dụng Internet phong phú, việc liên lạc với máy chủ thường diễn ra khi cần thiết, đặc biệt qua thủ tục gọi từ xa (RPC) Trong chương này, chúng ta sẽ khám phá các thủ tục RPC với bộ công cụ GWT, giúp tối ưu hóa quá trình giao tiếp giữa client và server Cơ chế GWT – RPC được trình bày để phân biệt rõ với các phương thức RPC chung khác, mang lại hiệu quả và độ tin cậy cao cho ứng dụng của bạn.
RPC (Remote Procedure Call) là một thuật ngữ mô tả cơ chế cho phép một chương trình thực hiện lệnh trên một máy tính từ xa, sau đó trả về kết quả của phép tính đó Đây là một phương pháp phổ biến trong lập trình phân tán giúp các hệ thống giao tiếp và chia sẻ dữ liệu hiệu quả Hiểu rõ RPC giúp phát triển các ứng dụng phân tán linh hoạt và mở rộng dễ dàng hơn.
4.1.1 Khái niệm cơ bản về RPC
Trong phần này, chúng tôi sẽ giải thích cơ chế hoạt động của GWT – RPC bằng cách xây dựng một thành phần mẫu để minh họa rõ cách thức hoạt động Mục đích của thành phần này là cung cấp bộ nhớ cập nhật liên tục, hỗ trợ hiệu quả cho vận hành của Java Virtual Machine (JVM).
Để làm việc với ứng dụng RPC, bạn cần lắp ráp ba thành phần chính: các dịch vụ chạy trên máy chủ, khách hàng trong trình duyệt, và các đối tượng dữ liệu được vận chuyển giữa máy khách và máy chủ Cả máy chủ và khách hàng đều có khả năng serialize và deserialize dữ liệu, giúp các đối tượng dữ liệu có thể truyền tải dễ dàng dưới dạng văn bản thông thường.
Hình 4.1 trình bày thành phần Server Status và ví dụ về quy trình yêu cầu dịch vụ và phản hồi Quá trình kết nối giữa khách hàng và máy chủ bắt đầu bằng yêu cầu của khách hàng thông qua đối tượng proxy do GWT cung cấp Đối tượng proxy sẽ serialize yêu cầu thành dạng văn bản và gửi đến máy chủ Trên máy chủ, yêu cầu được xử lý bởi servlet Java đặc thù của GWT, sau đó deserialize theo yêu cầu và gọi dịch vụ phù hợp Khi dịch vụ trả về kết quả, servlet GWT sẽ đóng gói và gửi phản hồi về cho khách hàng Cuối cùng, proxy GWT nhận phản hồi, deserialize dữ liệu thành đối tượng Java rồi trả về kết quả cho mã gọi của khách hàng.
Hình 4.1 mô tả ba phần chính của ứng dụng RPC: gồm các dịch vụ chạy trên máy chủ, trình khách hàng trong trình duyệt thực hiện các cuộc gọi dịch vụ, và các đối tượng dữ liệu được truyền tải giữa máy khách và máy chủ.
Cơ chế GWT – RPC bao gồm ba phần chính: dịch vụ chạy trên máy chủ dưới dạng servlet, trình duyệt web hoạt động như một khách hàng thực hiện các cuộc gọi dịch vụ, và các đối tượng dữ liệu được truyền giữa máy khách và máy chủ GWT – RPC cho phép gửi các đối tượng Java trực tiếp giữa client và server với mức công việc bổ sung tối thiểu ở cả hai phía.
Hình 4.2: Ba phần của GWT-RPC: khách hàng, máy chủ, và các đối tượng dữ liệu a Tìm hiểu đối tượng dữ liệu Serializable
Chúng ta cần bắt đầu thảo luận về GWT – RPC với các đối tượng dữ liệu, vì dữ liệu đóng vai trò là yếu tố cốt lõi để GWT – RPC hoạt động hiệu quả GWT-RPC cho phép gọi các phương thức trên máy chủ và truyền kết quả trả về cho phía khách hàng, giúp xây dựng các ứng dụng web tương tác và mượt mà hơn.
Thực hiện giao diện IsSerializable
Giao diện IsSerializable là một phần của thư viện GWT, được sử dụng để chỉ định rằng một lớp có thể được tuần tự hóa, tương tự như giao diện java.io.Serializable của Java nhưng dành riêng cho các ứng dụng GWT Hầu hết các phần của ứng dụng GWT sử dụng giao diện này để xác nhận khả năng tuần tự của các đối tượng, giúp quá trình truyền dữ liệu diễn ra hiệu quả hơn Giao diện IsSerializable không chứa phương thức nào và chỉ nhằm mục đích để trình biên dịch GWT nhận biết rằng đối tượng đó có thể được tuần tự hóa một cách an toàn.
Để hiển thị đối tượng dữ liệu Server Status, bạn cần xây dựng một lớp dữ liệu phù hợp, chứa thông tin về trạng thái máy chủ và thống kê cần thiết Lớp này nằm trong gói org.gwtbook.client và sẽ được biên dịch thành JavaScript để sử dụng trên trình duyệt của khách hàng, đảm bảo khả năng hoạt động mượt mà trên phía client Đồng thời, lớp này cũng được sử dụng trên máy chủ dưới dạng phiên bản Java đã biên dịch, hỗ trợ quá trình serialization dữ liệu để đồng bộ các dữ liệu giữa phía client và server một cách chính xác, nhờ vào quá trình xử lý bản đồ cho các lĩnh vực của lớp này trong hai môi trường khác nhau Bước tiếp theo là xác định dịch vụ GWT – RPC để hỗ trợ giao tiếp dữ liệu hiệu quả giữa client và server.
Bước tiếp theo trong sử dụng cơ chế GWT-RPC là xác định và triển khai các dịch vụ trên máy chủ Điều này đòi hỏi tạo một giao diện Java mô tả các dịch vụ cần thực hiện, đồng thời phát triển các phương thức xử lý dịch vụ đó Khi xây dựng dịch vụ phía máy chủ, bạn có thể muốn tích hợp nó với các hệ thống phụ trợ như cơ sở dữ liệu, máy chủ email và các dịch vụ khác để nâng cao tính năng và hiệu quả của ứng dụng.
Để xác định dịch vụ của bạn trong GWT, bạn cần tạo một giao diện Java và mở rộng giao diện RemoteService của GWT, điều này rất đơn giản Trong dự án Server Status, phương thức dịch vụ RPC trả về một đối tượng, giúp dễ dàng mở rộng và tùy chỉnh dịch vụ từ xa.
ServerStatusData chứa số liệu về các máy chủ khác nhau, cung cấp cái nhìn tổng quan về tình trạng hoạt động của hệ thống Giao diện RemoteService không định nghĩa phương thức nào, giúp quá trình tích hợp trở nên đơn giản và linh hoạt hơn cho các hoạt động dịch vụ Tuy nhiên, việc xác định các giao diện này đòi hỏi yêu cầu bổ sung, đôi khi khá tinh tế, để đảm bảo tính chính xác và hiệu quả trong quản lý dịch vụ máy chủ.
- Giao diện phải mở rộng com.google.gwt.user.client.rpc.RemoteService
- Tất cả các thông số phương thức và giá trị trả lại phải được serializable
- Giao diện phải sống trong gói khách hàng
GWT tự động tạo lớp proxy cho các ứng dụng phía khách hàng và chuyển tiếp các phương thức sử dụng phản chiếu trên máy chủ, giúp đơn giản hóa quá trình gọi RPC Giao diện RemoteService được sử dụng để định nghĩa các dịch vụ từ xa, cho phép dễ dàng tích hợp và mở rộng hệ thống Việc này làm cho RPC trở nên dễ dàng hơn bằng cách giảm thiểu lượng mã cần viết, giúp phát triển ứng dụng nhanh chóng và hiệu quả.
Để triển khai dịch vụ của bạn với giao diện xác định rõ ràng, bạn cần tạo một servlet mở rộng từ RemoteServiceServlet của GWT và thực hiện các giao diện dịch vụ đã xác định Việc này giúp kết nối giữa client và server được thực hiện một cách chính xác và hiệu quả Ví dụ 4.1 minh họa cách thực hiện hoàn chỉnh của ServerService, giúp bạn dễ dàng áp dụng và tùy chỉnh phù hợp với yêu cầu của dự án.
Kiểm tra kiến trúc client – side RPC
Chúng ta đã bắt đầu xây dựng thành phần Server Status nhằm hiển thị thông tin về Java Virtual Machine chạy trên máy chủ, bao gồm các chỉ số quan trọng như bộ nhớ và CPU Trong quá trình phát triển, chúng ta đã tìm hiểu cách sử dụng cơ chế GWT – RPC để giải quyết các vấn đề liên quan đến gửi dữ liệu giữa máy khách và máy chủ một cách hiệu quả.
Sau khi hoàn thành, chúng ta có một số mã nhưng chưa đạt đến mức hoàn hảo, còn thiếu phần cấu trúc logic rõ ràng cho các thành phần, cơ chế bỏ phiếu hoạt động hiệu quả, và quá trình đóng gói các thành phần để nâng cao khả năng sử dụng.
4.2.1 Cơ cấu lại các mã khách hàng
Trong phần này, chúng ta tiếp tục dự án Server Status và làm mịn nó để dễ dàng mở rộng, bảo trì Chúng ta áp dụng các mô hình phần mềm RPC bằng cách đóng gói các thành phần trạng thái máy chủ như một phần mở rộng của lớp GWT Composite, kèm theo mã RPC giúp đơn giản hóa việc tương tác Nhờ đó, các mẫu phần mềm như Façade và Command có thể được sử dụng để tối ưu hóa giao tiếp từ xa và giảm thiểu phức tạp trong quá trình gọi phương thức từ xa.
Bước đầu trong xây dựng thành phần là xác định bố cục hình ảnh cơ bản và xác định lớp widget cần mở rộng Đối với thành phần Server Status, hình 4.3 minh họa rõ ràng cấu trúc mong muốn và kết quả cuối cùng theo định dạng HTML, giúp đảm bảo tính trực quan và hiệu quả trong phát triển giao diện người dùng.
Các thành phần của Server Status được tổ chức trong một VerticalPanel gồm bốn phần chính Phần đầu tiên là thanh tiêu đề thể hiện tình trạng máy chủ, được tạo bằng một nhãn và có thể làm nổi bật hơn nhờ vào các tùy chỉnh CSS Điều này giúp người dùng dễ dàng nhận biết trạng thái của máy chủ một cách rõ ràng và trực quan.
Hình 4.3: Cấu trúc của các thành phần Server Status và những gì các thành phần hoàn thành
Thành phần thứ hai bạn sử dụng là một lưới (Grid) để hiển thị dữ liệu thống kê máy chủ lấy qua RPC, gồm hai cột và năm hàng cho các nhãn và giá trị dữ liệu như Server Name và Total Memory Các nhãn này được bổ sung vào lưới dưới dạng văn bản gốc, trong khi các giá trị riêng biệt được đặt trong các thành phần Label để dễ dàng cập nhật bằng phương thức setText() Bạn có thể thiết lập trực tiếp các văn bản trong lưới hoặc cung cấp ví dụ về tên Label cho từng giá trị để giúp dễ hiểu và duy trì mã nguồn hơn Ở cuối phần của "Server Status" là một thành phần cập nhật dữ liệu mới.
Button được sử dụng để tự cập nhật các số liệu thống kê, giúp người dùng dễ dàng làm mới dữ liệu khi cần thiết Một Label đi kèm sẽ cho biết thời gian gần nhất các giá trị đã được cập nhật, nâng cao tính minh bạch và tiện lợi trong theo dõi dữ liệu Thành phần này dự kiến sẽ sử dụng các cơ chế bỏ phiếu để cập nhật tự động định kỳ, đảm bảo dữ liệu luôn mới nhất Ngoài ra, nút cập nhật hướng dẫn sử dụng có thể được nhấn để buộc một lần cập nhật sớm, mang lại sự kiểm soát linh hoạt cho người dùng.
Cuối cùng chúng ta thu được một phiên bản gần như hoàn thiện
Hình 4.4: Một phiên bản gần như hoàn chỉnh của ví dụ thành phần Server Status b Đúng gúi cuộc gọi từ xa trong Faỗade
Mặt dựng Façade giúp cung cấp một giao diện cao cấp hơn, làm cho hệ thống phụ dễ dàng sử dụng và quản lý hơn Trong trường hợp này, việc đóng gói tất cả các logic RPC vào một lớp Façade giúp đơn giản hóa việc truy cập và sử dụng các chức năng của hệ thống Để đạt được mục tiêu này, cần thực hiện các bước như tạo lớp Façade để bao bọc các phương thức RPC phức tạp, đảm bảo giao diện rõ ràng và dễ sử dụng cho người phát triển Việc sử dụng mẫu thiết kế Façade không những tối ưu hoá quy trình phát triển mà còn nâng cao khả năng bảo trì, mở rộng hệ thống trong tương lai.
- Giảm độ phức tạp bằng cách giảm số lượng các lớp bạn cần phải tương tác
- Thúc đẩy khớp nối yếu, cho phép bạn thay đổi cơ chế RPC cơ bản mà không ảnh hưởng đến khách hàng
4.2.2 Kiểm tra kỹ thuật bỏ phiếu khác nhau
Để giữ khách hàng được cập nhật với các sự kiện như email mới hoặc tin nhắn trò chuyện, bạn cần duy trì liên lạc thường xuyên với máy chủ qua cuộc gọi RPC Giải pháp này thường thực hiện bằng cách thăm dò ý kiến máy chủ định kỳ, ví dụ mỗi năm phút, hoặc thậm chí nhanh hơn để phù hợp với yêu cầu của các ứng dụng cần cập nhật thời gian thực Trong phần này, chúng ta sẽ tìm hiểu chức năng của GWT trong các nhiệm vụ lập kế hoạch và kiểm tra kỹ thuật bỏ phiếu, đặc biệt tập trung vào kỹ thuật giao tiếp giữa server push và client pull để tối ưu hóa quá trình cập nhật dữ liệu.
Kỹ thuật giao tiếp trong hệ thống có thể được chia thành hai loại chính là server push và client pull Server push xảy ra khi máy chủ chủ động đẩy nội dung đến khách hàng mà không cần họ yêu cầu, giúp truyền tải dữ liệu nhanh chóng và hiệu quả Ngược lại, client pull yêu cầu khách hàng gửi yêu cầu dữ liệu đến máy chủ, và máy chủ phản hồi dựa trên yêu cầu này, phù hợp với các tình huống yêu cầu kiểm soát và lấy dữ liệu theo nhu cầu Điểm khác biệt nổi bật giữa hai phương pháp này là ai là người bắt đầu yêu cầu hoặc truyền dữ liệu trong quá trình giao tiếp.
Server push là hoạt động gửi dữ liệu tự động hàng ngày, ví dụ như khi bạn gửi email hoặc tin nhắn Khi gửi email, dữ liệu được đẩy từ máy chủ gửi đến máy chủ nhận, đảm bảo quá trình truyền tải diễn ra nhanh chóng và hiệu quả Tương tự, với tin nhắn tức thời, nội dung tin nhắn được đẩy trực tiếp đến người nhận, giúp giao tiếp nhanh chóng và thuận tiện hơn Hiểu rõ về server push giúp tối ưu hóa quá trình truyền thông số trong hoạt động hàng ngày.
Bằng cách đẩy dữ liệu cho khách hàng, bạn có thể mở rộng lượng khách hàng một cách dễ dàng mà không gây quá tải cho tài nguyên máy chủ hoặc băng thông Điều này giúp tối ưu hóa khả năng hỗ trợ số lượng khách hàng lớn, đồng thời đảm bảo chương trình hoạt động hiệu quả và ổn định Phương pháp này là chiến lược quan trọng để tăng trưởng khách hàng và nâng cao trải nghiệm người dùng trong các dịch vụ cung cấp dữ liệu.
Client pull là một thuật ngữ dùng để chỉ trình tự đáp ứng yêu cầu tiêu chuẩn của trình duyệt khi truy cập một URL Khi bạn nhập một địa chỉ trang web, trình duyệt gửi yêu cầu đến máy chủ để tải trang, còn gọi là kéo trang từ máy chủ Kỹ thuật này giúp giảm thiểu thời gian chậm trễ giữa thao tác của người dùng và việc nhận được phản hồi phù hợp, đảm bảo trải nghiệm duyệt web mượt mà hơn.
Client pull đối mặt với những thách thức riêng như việc chậm trễ giữa gửi và nhận dữ liệu, yêu cầu xếp hàng dữ liệu trên máy chủ để đợi khách hàng kiểm tra Ví dụ, trong ứng dụng chat, máy chủ cần lưu trữ các tin nhắn chưa gửi cho người dùng cho đến khi họ truy cập để lấy tin nhắn mới nhất Để đảm bảo trải nghiệm người dùng mượt mà, cần thực hiện các thành phần liên tục cập nhật dữ liệu một cách hiệu quả và chính xác.
Trong phần này, chúng ta sẽ xem xét các thành phần của trạng thái máy chủ (Server Status) và cách cho phép nó tự động cập nhật định kỳ Bạn có thể thiết lập tỷ lệ làm mới dữ liệu để giữ thông tin luôn mới nhất, đồng thời cung cấp tùy chọn để thay đổi hoặc tắt chức năng tự động cập nhật khi cần thiết Để thực hiện điều này, chúng ta sẽ sử dụng lớp Timer của GWT, giúp kích hoạt các sự kiện theo thời gian một cách chính xác và hiệu quả.
Hình thức Ajax cổ điển và HTML
Trong bài viết này, chúng ta sẽ tìm hiểu về hai công cụ phổ biến là RequestBuilder và FormPanel, cả hai đều giúp truyền dữ liệu từ phía người dùng đến máy chủ Việc so sánh giữa hai công cụ này đặt ra câu hỏi quan trọng: công cụ nào tối ưu và phù hợp hơn để xử lý việc gửi dữ liệu?
RequestBuilder là công cụ lý tưởng khi cần gửi hoặc yêu cầu dữ liệu từ máy chủ mà không cần hiển thị giao diện người dùng, vì nó dễ sử dụng và xử lý lỗi hiệu quả Nó cho phép truy cập mã trạng thái của máy chủ để xử lý các lỗi một cách phù hợp, đồng thời hỗ trợ thiết lập thời gian chờ, hủy bỏ yêu cầu và cấu hình các tiêu đề gửi đến máy chủ.
FormPanel gửi dữ liệu đến máy chủ bằng cách gói chức năng hiện có như mẫu
HTML xuất hiện trong các trình duyệt web, giúp gửi dữ liệu người dùng đến máy chủ thông qua các biểu mẫu RequestBuilder làm việc để xử lý các yêu cầu và đăng ký sự kiện với FormPanel, theo dõi các hoạt động của biểu mẫu Khi dữ liệu được gửi, kết quả phản hồi của máy chủ được gửi về trong một khung ẩn, cho phép mã đọc và xử lý để cung cấp phản hồi phù hợp cho người dùng.
4.3.1 Ajax cổ điển với RequestBuilder Đối tượng XMLHttpRequest là một công cụ mà là một phần của các trình duyệt hiện đại, có thể liên quan với JavaScript Đối tượng XMLHttpRequest này cho phép bạn lấy nội dung từ một URL từ xa và xử lý các phản ứng lập trình Lợi ích của việc tải nội dung theo cách mà bạn có thể sử dụng mã để giao tiếp với máy chủ mà không cần phải làm mới trang web, làm cho các ứng dụng web của bạn cảm thấy giống như một ứng dụng máy tính để bàn và dễ dùng hơn Cơ chế GWT – RPC mà bạn đã tìm hiểu là một công cụ cao cấp được xây dựng trên đầu trang của đối tượng này
Chúng ta bắt đầu với tổng quan về giao thức HTTP và sự khác biệt giữa phương thức GET và POST, nhằm xây dựng nền tảng cho việc khám phá RequestBuilder RequestBuilder cung cấp giao diện đơn giản và hợp lý để thực hiện các cuộc gọi từ xa đến máy chủ mà vẫn giữ khả năng tùy chỉnh các chi tiết cấp thấp của yêu cầu, như thay đổi tiêu đề HTTP hoặc xác định thời gian chờ Việc kiểm tra các phương thức HTTP sẽ giúp hiểu rõ hơn về cách gửi và xử lý dữ liệu trên server.
Khi tải một trang web vào trình duyệt, Hypertext Transfer Protocol (HTTP) được sử dụng để trao đổi dữ liệu giữa trình duyệt và máy chủ HTTP liên quan đến các yêu cầu và phản hồi, trong đó trình duyệt gửi yêu cầu đến máy chủ và máy chủ gửi phản hồi trở lại Mỗi yêu cầu HTTP bao gồm một phương thức, URL, tiêu đề cặp tên-giá trị, và có thể đi kèm với một tin nhắn Trong công nghệ GWT, hai phương thức chính được sử dụng là GET và POST, vì đây là các phương thức hỗ trợ duy nhất bởi GWT để thực hiện các giao tiếp với máy chủ.
GET và POST có thể được sử dụng để gửi dữ liệu đến máy chủ, nhưng cách thực hiện điều thì khác nhau b Phân tích phương thức GET HTTP
Lệnh GET gửi tất cả dữ liệu của nó thông qua URL, giúp truyền tham số một cách rõ ràng và dễ dàng theo dõi Ví dụ, URL để thực hiện tìm kiếm Google cho từ khóa "GWT" là: http://www.google.com/search?hl=en&q=GWT&btnG=Google%2Bsearch Điều này cho thấy dữ liệu tìm kiếm được đính kèm trực tiếp trong URL, giúp người dùng và công cụ tìm kiếm dễ dàng xử lý và phân tích thông tin.
Khi trình duyệt của bạn gửi yêu cầu URL tới google.com, nó sẽ gửi tin nhắn GET sau đây bằng cách sử dụng HTTP:
GET /search?hl=en&q=GWT&btnG=Google%2BSearch HTTP/1.1 Host: www.google.com
URL vẫn giữ nguyên, ngoại trừ việc tên máy chủ đã được thêm vào để làm tiêu đề rõ ràng hơn Chúng tôi đã chỉ định các tiêu đề chính, nhưng bạn có thể sử dụng bất kỳ số lượng cặp tên – giá trị bổ sung nào để xác định thông tin về trình duyệt của bạn một cách chính xác và tiện lợi.
Phần quan trọng trong URL là phần truy vấn, giúp truyền dữ liệu từ trình duyệt đến máy chủ một cách hiệu quả Dấu hỏi (?) trong URL phân biệt phần truy vấn, chứa các cặp tên và giá trị được phân cách bởi dấu & và dấu = để tách tên ra khỏi giá trị Trong quá trình trao đổi dữ liệu, phương thức GET và POST đóng vai trò khác nhau; GET thường dùng để truyền dữ liệu qua URL, phù hợp cho các truy vấn không gây thay đổi dữ liệu, còn POST gửi dữ liệu trong thân yêu cầu, thích hợp cho các tác vụ cần bảo mật và xử lý dữ liệu lớn hơn.
Phương thức POST thường được sử dụng trong các biểu mẫu HTML để truyền nhiều dữ liệu đến máy chủ Khác với phương thức GET, POST gửi dữ liệu qua body của thông điệp HTTP thay vì đính kèm trong URL Trong HTTP, lệnh và tiêu đề được tách biệt với phần thân (body) bằng một dòng trống duy nhất Khi sử dụng GET, truy vấn đơn giản và gắn liền với URL, còn với POST, dữ liệu được gửi trong phần body giúp xử lý thông tin phức tạp hơn.
POST /search HTTP/1.1 Host: www.google.com Content-type: application/x-www-form-urlencoded Content-length: 32 hl=en&q=GWT&btnG=Google%2BSearch d RPC đơn giản với RequestBuilder
Lớp RequestBuilder cho phép bạn gọi một URL và đăng ký một xử lý để nhận kết quả, hoạt động tương tự như GWT – RPC nhưng chỉ gửi và nhận dữ liệu văn bản Bất kỳ dữ liệu nào không phải dạng văn bản, như ngày tháng, đều phải chuyển đổi sang dạng văn bản trước khi gửi Dữ liệu có thể được gửi qua phương thức GET hoặc POST; trong đó, GET mã hóa dữ liệu trong URL, còn POST cho phép truyền dữ liệu dựa trên dạng văn bản một cách linh hoạt hơn Cả hai phương thức này đều hỗ trợ tùy chọn cung cấp tên người dùng và mật khẩu để truy cập tài nguyên máy chủ, mặc dù thường không cần thiết, nhưng có thể hữu ích trong các trường hợp yêu cầu xác thực.
RequestBuilder, part of the com.google.gwt.http.client package, is a key component of the HTTP model in GWT To utilize RequestBuilder, it must be properly initialized with its constructor, which requires two parameters: an HTTP method and a target URL The HTTP method can be either RequestBuilder.GET or RequestBuilder.POST, specified using static constants Proper configuration of RequestBuilder is essential for making successful HTTP requests within GWT applications.
4.3.2 Các vấn đề cơ bản của FormPanel
Kỹ thuật tạo khung nội tuyến ẩn là phương pháp phổ biến để gửi và nhận dữ liệu mà không tải lại trang, bằng cách tải nội dung vào khung qua JavaScript và chuỗi truy vấn Sau khi khung nội tuyến được nạp, bạn có thể kiểm tra nội dung trang ẩn để xem dữ liệu trả về FormPanel sử dụng kỹ thuật này để cho phép gửi phản hồi từ máy chủ mà không làm mới trang, phù hợp để trình bày các điều khiển đầu vào cho người dùng và gửi dữ liệu mẫu đến máy chủ xử lý Mặc dù có thể sử dụng GWT RPC hoặc RequestBuilder, nhưng phương pháp này yêu cầu viết nhiều mã hơn để đạt hiệu quả tương tự.
Hình thức HTML được xây dựng với thẻ chứa các control form để người dùng nhập dữ liệu Mỗi control đều có tên riêng như FullName, StreetAddress, CityState, và PhoneNumber để dễ dàng xác định dữ liệu Thông thường, các mẫu đăng ký còn có nút gửi dữ liệu đến máy chủ, dùng thuộc tính phương thức để chọn loại HTTP phù hợp, như POST hoặc GET Ví dụ về một form HTML sẽ minh họa cách các yếu tố này được tổ chức để gửi dữ liệu đến máy chủ một cách hiệu quả.
Khi người dùng nhấn nút submit, dữ liệu sẽ được gửi đến máy chủ theo URL được chỉ định bởi thuộc tính hành động của hình thức Chỉ các điều khiển bên trong các yếu tố hình thức mới được gửi đi, cho phép tạo nhiều biểu mẫu trên cùng một trang với các hành động khác nhau, ví dụ như hình thức tìm kiếm và đăng ký.