Công nghệ AJAX

doc 51 trang phuongnguyen 2840
Bạn đang xem 20 trang mẫu của tài liệu "Công nghệ AJAX", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • doccong_nghe_ajax.doc

Nội dung text: Công nghệ AJAX

  1. Tựa đề Phần 1: Tìm hiểu công nghệ AJAX. 1.1 Lich sử phát triển công nghệ web động: 1.1.1 CGI (Common Gateway Interface) Ưu điểm: CGI chạy được trên nhiều ngôn ngữ và là ngôn ngữ đầu tiên hổ trợ viết web động. Khuyết điểm: Người dùng có thể thao tác bên trong hệ thống bằng cách thực thi một chương trình trên hệ thống. Tuy vậy CGI vẫn còn được sử dụng đến nay, nhưng không thể phát triển hơn. 1.1.2 Applet Tháng 5 năm 1995, John Gage of Sun and Andreessen(now of NCC) tuyên bố sự ra đời của ngôn ngữ lập trình Java. Ưu điểm: Applet cho phép nhúng những ứng dụng nhỏ vào các trang web. Applet được chạy trên máy ảo java (Java Vitual Machine) của trình duyệt browser. Khuyết điểm: Ngăn cấm việc đọc và ghi trên file hệ thống, không load được thư viện có sẵn, không chạy được chương trình trên client nếu client không hổ trợ máy ảo java. 1.1.3 JavaScript Ưu điểm: Hỗ trợ tương tác ở phía client và tránh quá tải tại phía server. Khuyết điểm: Sẽ không làm việc nếu trình duyệt không cho phép. 1.1.4 Servlet and ASP and PHP Ưu điểm: là các ngôn ngữ script giúp cho chúng ta xây dựng ứng dụng web động dễ dàng. Trong đó, PHP là cho ngôn ngữ PHP, ASP dùng ngôn ngữ ASP và Servlet dùng ngôn ngữ Java. 1.1.5 Flash Năm 1996 FutureWave cho ra đời một sản phẩm với tên gọi FutureSplash Animator. Sau khi FutureWave bán công ty cho Macromedia, FutureSplash Animator được đóng dấu với tên gọi Flash. Ưu điểm: Flash gây ngạc nhiên bởi khả năng thiết kế Web động vượt trội và Không đòi hỏi kỹ thuật lập tình, dễ hiểu và dễ học. Khuyết điểm: Đòi hỏi trình duyệt phải cài phần mềm hổ trợ Flash. 1.1.6 Ajax Phương pháp tải không đồng bộ nội dung trên một trang web đã xuất hiện trong thành tố IFRAME của Internet Explorer 3 (1996) và thành tố LAYER của Netscape 4.0 năm 1997. Tuy nhiên, hầu hết các câu chuyện về nguồn gốc của AJAX được bắt đầu từ khi Microsoft phát triển công nghệ Remote Scripting vào năm 1998. Khi giới thiệu Internet Explorer 4.0, Microsoft đã sử dụng mô hình đối tượng DOM khác biệt. Đến năm 2000, Netscape hoàn toàn đánh mất thị trường trình duyệt vào tay hãng phần mềm của Bill Gates và thành tố LAYER cũng không còn được các chuyên gia phát triển web chú ý tới. Vài năm sau, AJAX mới tạo được sự quan tâm của giới công nghệ và trở thành công cụ cải tiến giao diện người dùng cho ứng dụng web Thuật ngữ này cũng chỉ mới xuất hiện cách đây 1 năm (tháng 2/2005) trong bài viết nổi tiếng của Jesse James Garrett trên trang Adaptive Path. Từ đó, AJAX trở thành trung tâm trong mọi câu chuyện liên quan đến thế hệ Web 2.0.
  2. 1.2 Giới thiệu công nghệ Ajax 1.2.1 Khái niệm Ajax viết tắt của "Asynchronous JavaScript and XML". Ajax được xây dựng từ các công nghệ phổ biến: JavaScript và XML và sự truyền thông bất đồng bộ giữa Browser và Server. Ajax Là một kỹ thuật phát triển web nhằm tạo ra những ứng dụng web có tính tương tác và Là bộ công cụ cho phép tăng tốc độ ứng dụng web bằng cách cắt nhỏ dữ liệu và chỉ hiển thị những gì cần thiết, thay vì tải đi tải lại toàn bộ trang web. Giống như DHTML, LAMP hay SPA, Ajax tự nó không phải là một công nghệ mà là một thuật ngữ mô tả việc kết hợp một nhóm nhiều công nghệ với nhau.Khi được định nghĩa, nó được hình dung như sau: Việc thể hiện dựa trên những chuẩn, sử dụng XHTML và CSS(Cascading Style Sheet) Việc tương tác và hiên thị động, sử dụng DOM (Document Object Model). Việc vận dụng và trao đổi sử dụng XML và XSLT . 1Việc thu hồi dữ liệu bất đồng bộ sử dụng XMLHttpRequest hoặc XMLHTTP(từ Microsoft). JavaScript gắn kết tất cả các kỹ thuật trên lại với nhau. 1.2.2 Các trình duyệt hổ trợ Ajax Konqueror Microsoft Internet Explorer từ 4.0 trở lên Mozilla/ Mozilla Firefox từ 1.0 trở lên Netcapse từ 7.1 trở lên Opera từ 7.6 trở lên 1.2.3 Các công cụ phát triển Ajax Atlas, toolkit Ajax của Microsoft Dojo Toolkit, toolkit Ajax/DHTML Prototype, khuôn khổ mã nguồn mở Sajax, toolkit Ajax đơn giản 1 Rialto (Rich Internet AppLication TOolkit) 1.2.4 Một số web site đang sử dụng Google suggest Google Maps Gmail Những dự án trên cho thấy Ajax không phải là một công nghệ quá xa xôi mà đang hiện diện ngay trong thế giới thực, từ mô hình rất đơn giản như Google Suggest đến tinh vi và phức tạp như Google Maps. 1.2.5 Ưu Khuyết điểm Ưu điểm: Mọi thao tác của người sử dụng sẽ gửi lệnh JavaScript tới bộ xử lý Ajax, thay vì tạo ra một yêu cầu HTTP (HTTP request) và truy vấn tới máy chủ. Nếu cần gì từ server, như tải về bổ sung mã giao diện hay nhận dữ liệu mới, Ajax sẽ truyền yêu cầu tới máy chủ một cách không đồng bộ, thông thường sử dụng XML, mà không làm gián đoạn sự tương tác của người dùng với ứng dụng web. Do đó người dùng không phải chờ đợi server thực hiện, các giao dịch sẽ trở nên dễ dàng và nhanh chóng hơn. Khuyết điểm: Không thể lưu lại địa chỉ web vào thư mục Bookmark (hỗ trợ xem lại về sau) vì các ứng dụng Ajax không có một địa chỉ cố định cho từng nội dung và không xem được nội dung offline
  3. 1.3. Ví dụ đơn giản sử dụng Ajax: 1.3.1. Phát biểu bài toán: Chúng ta xây dựng một ứng dụng web để quản lý thông tin khách hàng. Màn hình ứng dụng gồm có các text field: Customer Name – tên khách hàng, Post Code – mã vùng, và Province/City – tên tỉnh/thành phố. Khách hàng được yêu cầu nhập Customer Name và Post Code, nếu Post Code được nhập hợp lệ thì tên tỉnh/thành phố thích hợp sẽ được tự động thể hiện trên text field Province/City. Màn hình ứng dụng 1.3.2. Cách giải quyết: Không dùng Ajax: Theo cách làm trước đây của một web application thì buộc người dùng phải nhập tất cả các trường, sau đó gửi đi một lượt để server xử lý và một khuyết điểm kèm theo là trang jsp/ servlet phải refresh gây khó chịu cho người dùng. Rất may mắn công nghệ Ajax ra đời để giải quyết vấn đề trên. Dùng Ajax: Ví dụ 1 Phía client : File CustomerData.html Customer Data Screen var xhr; function createXHR() {  try {
  4. xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xhr = false; } } if (!xhr && typeof XMLHttpRequest != 'undefined') { xhr = new XMLHttpRequest(); } return xhr; } function getPostCode(postCode) { this.createXHR(); xhr.onreadystatechange = processPostCode;  xhr.open("GET", "serverservlet?postCode="+ postCode);  xhr.send(null); } function processPostCode() { if (xhr.readyState == 4) { if (xhr.status == 200) { assignProvince(xhr.responseText);  } } } function assignProvince(data){ var provNError = data.split(","); document.getElementById("province").value = provNError[0];  document.getElementById("codeError").innerHTML = provNError[1];  } Enter Customer Data Customer Name: Post Code: 
  5. Province/City:   Thuộc tính onblur là một Event handler – cho phép thực hiện một đoạn script code trên trang web khi có user tương tác hay khi xuất hiện browser tasks. Nghĩa là, khi nhấn tab hay click chuột ở bất cứ vị trí nào (ngoài text field Post Code) thì function getPostCode() sẽ được gọi, tham số truyền cho function này là this.value: - this có nghĩa tham khảo đến element mà event handler được đăng ký ( element) - value là thuộc tính của element đó.  Thuộc tính id sẽ được dùng ở phần xủ lý response.  Khởi tạo đối tượng XMLHttpRequest – giải thích ở phần Giới thiệu về XMLHttpRequest.  onreadystatechange: là thuộc tính của XMLHttpRequest, nó xác nhận rằng XMLHttpRequest đã nhận được response từ Server.  Function open(), tham số đầu tiên cho biết phương thức HTTP dùng để gởi request, tham số thứ hai là URL.  xhr.responseText: Nhận dữ liệu từ Server ở dạng Text.  document.getElementById() trả về một tham khảo đến bất kỳ element XML nào dựa vào thuộc tính id. Trong trường hợp này chúng ta set thuộc tính value của element có id="province" bằng giá trị tỉnh/thành phố trả về từ Server.  Nếu User nhập vào post code không hợp lệ thì Server gởi về thông báo lỗi, và nó sẽ được set thành value của một element với id="codeError". Phía server: File ServerServlet.java package postcode_text; import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class ServerServlet extends HttpServlet { private static Map postCodeMap = new HashMap();
  6. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String code = request.getParameter("postCode"); Object codeObj = postCodeMap.get(code); if(codeObj != null) out.println(codeObj.toString() + ", "); else out.println(" ," + "Invalid Post Code"); } public void init() throws ServletException { postCodeMap.put("04", "Ha Noi"); postCodeMap.put("08", "Tp HCM"); postCodeMap.put("054", "Hue"); postCodeMap.put("055", "Quang Ngai"); postCodeMap.put("061", "Dong Nai"); } } Hình kết quả.
  7. 1.4 Giới thiệu về XMLHttpRequest: 1.4.1. Định nghĩa: XMLHttpRequest là đối tượng được dùng để gửi request và nhận response. Trong Internet Explore, XMLHttpRequest thể hiện dưới dạng một ActiveX Object. Còn trong các trình duyệt khác như: FireFox, Safari, Opera, XMLHttpRequest thể hiện dưới một đối tượng JavaScript được hỗ trợ sẵn. Nên trong mã JavaScript ta phải khởi tạo một XMLHttpRequest bằng cách dùng ActiveX Object và JavaScript Object. Đầu tiên kiểm tra trình duyệt có hỗ trợ ActiveX Object hay không nếu không thì tạo XMLHttpRequest như một JavaScript Object thông thường. Ví dụ: var xmlHttp;  function createXMLHttpRequest() { if (window.ActiveXObject) {  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) {  xmlHttp = new XMLHttpRequest(); } } : Tạo một biến toàn cục xmlHttp. : Kiểm tra xem trình duyệt có hỗ trợ ActiveX Object hay không, nếu có (Đây chính là Internet Explore) thì tạo một ActiveX Object thông qua một chuỗi để chỉ định loại ActiveX Object nào, ở đây chính là “Microsoft.XMLHTTP”. Sau đó gán cho biến toàn cục. : Nếu trình duyêt không hỗ trợ ActiveX Object, thì kiểm tra xem trình duyệt có hỗ trợ đối tượng XMLHttpRequest không. Nếu có hỗ trợ thì tạo XMLHttpRequest như một đối tượng JavaScript thông thường và gán cho biến toàn cục 1.4.2. Phương thức và thuộc tính: Phương thức:  open(String method, string url, boolean asynch, string username, string password) hay open(String method, string url): method: phương gưuir đi, bạn phải nhận vào tên phương thức(GET, POST hay PUT) url: trang servlet, JSP hay PHP, mà bạn sẽ gọi tới. asynch: tùy chọn này có nghĩa là bất đồng bộ, với biến này bạn có thể bỏ qua vì mặc định là true. Nếu chọn false, xử lý sẽ chờ khi nào response được gửi tới mới tiếp tục. Lời khuyên được đưa ra là true. Username, password: tên của chúng đã tự nói lên ý nghĩa của chúng rồi.  void send(content): phương thức này thực sự gửi request tới server, nếu request khai báo là bất đồng bộ(asynchronous) thì phương thức này trả về ngay lập tức, ngược lai sẽ chờ cho tới khi nhận được response. content: có thể là DOM object, input stream, hay String. Và nội dung của content được gửi như một phần của request.  void setRequestHeader(string header, string value): dùng để gán giá trị cho một giá trị trong header của HTTP request theo ý muốn. Phương thức này phải được gọi sau phương thức open().  abort(): Dùng để dừng request.
  8.  getAllResponseHeaders(): Trả về một chuỗi chứa tất cả headers của response. Header bao gồm: Content-Length, Date, and URI.  getResponseHeader( String header): Nhận vào một tham số thể hiện giá trị của header mà bạn muốn, trả về giá trị dưới dạng chuỗi. Thuộc tính  onreadystatechange Sự kiện sẽ được tiến hành khi trạng thái thay đổi, thường là gọi tới một hàm JavaScript  readyState . Trạng thái của request. Có năm giá trị: 0 (Uninitialized): đối tượng được tạo nhưng phương thức open() chưa được gọi. 1 (Loading): phương thức open() đã được gọi nhưng request chưa được gửi. 2 (Loaded): Request đã được gửi. 3 (Interactive). Một phần response được nhận. 4 (Complete): Tất cả dữ liệu được nhận từ response và kết nối được đóng  responseText: Response từ server dưới dạng chuỗi.  responseXML. Response từ server dưới dạng XML, đối tượng này có thể được phân tích và kiểm tra như một DOM object.  status. Trạng thái mã(code) từ server. Ví dụ: 200: OK, 400: Not Found,  satusText: text ví dụ OK hay Not Found, 1.4.3. Mô hình tương tác giữa client và server: Không giống như Web application thông thường, Ajax application có một số khác biệt 1. Client-side event thực hiện một ajax event. Bạn có thể thực hiện thông qua đoạn code như sau: 2. Tạo một XMLHttpRequest. Dùng phương thức open() để đưa vào phương thức gửi (GET hay POST) và URL. Request thật sự thực hiện thông qua việc gọi phương thức send(). Mã(code) có thể như sau: var xmlHttp; function validateEmail() { var email = document.getElementById("email"); var url = "validate?email=" + email.value;
  9. if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } xmlHttp.open("GET", url); xmlHttp.onreadystatechange = callback;  xmlHttp.send(null);  }  callback: chính là hàm sẽ xử lý khi có response gửi về. hàm này sẽ được đê cập sau.  ở đây send(null) có nghĩa ta chỉ gửi biến kèm theo url không kem theo bất cứ file nào khác. 3. request gọi tới server có thể là servlet, CGI script, 4. Server thực hiện yêu cầu. 5. Request được trả về trình duyệt, Content-Type có thể được gán bằng text/xml – XMLHttpRequest Object có thể xủ lý cả kêt quả text/html, hoặc phức tạp hơn JavaScript, DOM, 6. Trong ví dụ trên, ta cấu hình XMLHttpRequest object gọi hàm callback()(*) khi xử lý trả về. Hàm này sẽ kiểm tra thuộc tính readyState trong XMLHttpRequest, sau đó sẽ thực hiện một số hành động đối với dữ liệu được gửi về. function callback() { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { //do something interesting here } } } Kết luận: Rõ ràng có một số khác biệt nhỏ khi bạn tạo, thực hiện với XMLHttpRequest và khi gọi hàm callback() bạn phải kiểm tra states và status. Thường thì bạn sẽ đưa những điều này vào một thư viện để tiện cho việc sử dụng. 1.4.4. Phân biệt Post và Get: Chúng ta thường tự hỏi sự khác biệt giữa GET và POST cũng như khi nào thì dùng một trong hai cách trên. GET: Theo lý thuyết thì dùng GET khi request là idempotent có nghĩa là nhiều request sẽ cùng trả về kết quả tương tự. Thực tế thì nếu như hàm tương ứng trên server có thay đổi trạng thái theo một cách nào đó, thì điều trong lý thuyết thật sự không đúng. Nhưng nhìn chung thì GET dùng gọi thông tin từ server, nói cách khác, tránh thay đổi trạng thái trên servet với GET. POST: Ngược lại với GET, dùng POST khi có sự thay đổi trạng thái trên server. Khi dùng POST có một số khác biệt. Phải có thêm dòng: xmlHttp.setRequestHeader("Content-Type","application/x-www-form- urlencoded");
  10. Ví dụ: Thường thì gọi POST theo thứ tự sau: xmlHttp.open("POST", url, true); xmlHttp.onreadystatechange = handleStateChange; xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-rlencoded;"); xmlHttp.send(xml);  : send(xml): có nghĩa ta có thể kem theo một file xml, hay file dạng khác khi gửi request bằng phương thức POST 1.4.5. So sánh giữa iframe và XMLHttpRequest. Iframe Ưu điểm: Ưu điểm lớn nhất của iframe là việc lưu giữ history của trình duyệt, do đó có thể cho phép người dùng sử dụng nút Back và Forward. Lý do là frame lưu dấu của tất cả request thực hiện thông qua nó. Ngược lại trang chính của Ajax application không thay đổi, thật sự nút Back và Forward di chuyển trong history của iframe thay vi trang chính. Chú ý: IE lưu giữ history của iframe, Firefox chỉ lưu giữ HTML của iframe(không JavaScript ), Safari không lưu giữ history của iframe. Khuyết điểm: Chúng ta chỉ có thể biết rất ít thông tin về những gì xảy ra bên dưới (behind the scenes). Nếu như iframe không load được trang, không có bất cứ gì thông báo đã xảy ra khi có vấn đề. Trang chính vẫn chờ cho đến khi hàm JavaScript được gọi. Ta có thể cho một lượng thời gian nếu sau đó không có gì xảy ra thì thông báo đã gặp vấn đề. Hoặc dùng một cách khác XMLHttpRequest XMLHttpRequest: Ưu điểm: Code được viết rõ ràng hơn. Chúng ta có thể gọi các thành phần của request và response như headers, status code, giúp bạn biết được request đã thành công hay chưa. Khuyết điểm: History của trình duyệt không được lưu giữ, có nghĩa là Back và Forward bị vô hiệu hóa. Một khuyết điểm khác bởi vì trong IE XMLHttpRequest dựa trên ActiveX, điều này có lien quan đến vấn đề bảo mật, một số người dùng không cho phép ActiveX. Trong trường họp này mặc định dùng hidden frame
  11. 1.5. Các ứng dụng phổ biến của AJAX: 1.5.1 Performing Validation: Ứng dụng này có chức xác nhận tính hợp lệ của giá trị nhập vào là kiểu Date, nếu ta nhập vào 1 chuỗi các ký tự hay kiểu Date không lệ mà server không thể chuyển sang định dạng Date thì Server sẽ gởi thông báo lỗi màu đỏ, nếu hợp lệ thì hệ thống sẽ thông báo chữ màu xanh. Thông báo lỗi khi nhập vào các kí tự bất kì Thống báo lỗi khi nhập kiểu Date không hợp lệ
  12. Thông báo là kiểu bạn nhập đã hợp lệ 1.5.2 Reading Response Headers: Ứng dụng này chứng minh các cách khác nhau mà bạn có thể tìm lại response headers từ XMLHttpRequest Object và dùng chúng cho mục đich thực hành. Trang có 4 liên kết trên nó áp dụng phương thức khác nhau trên XMLHttpRequest object để đọc response headers. Click vào liên kết 1 hiển thị tất cả response header của Sever Đọc 1 response header đơn, ở đây là: ngày giờ Modify resource lần cuối cùng(click vào liên kết 2)
  13. Resource Web có giá trị (Server có tồn tại).(click vào liên kết 3). Resource Web không giá trị (Server không có tồn tại).click vào liên kết 4
  14. 1.5.3 Dynamically Loading List Boxes Ứng dụng dưới đây chứng minh cách mà chúng ta dùng công nghệ Ajax để tự động tạo ra nội dung của một select box trên những giá trị của 2 list box khác nhau. Khi người dùng chọn model year select box và manufacturer select box để xác định nội dung model select box. Ứng dụng này dùng chỉ 4 model years, 3 manufacturers, and four models. Khi khách hàng model year và manufacturers(make) thì list của model đươc hiện ra. Cửa sổ ban đầu, khi ta chưa chọn gì hết Tuỳ vào giá trị Model Year và Make do ta chọn, sẽ có list Models tương ứng
  15. 1.5.1.4 Creating an Autorefreshing Page Tạo một trang tự refresh một cách tự động. Sau 1 khoảng thời gian do ta quy định thì Client sẽ tự load dữ liệu được gởi từ phía Server. Ứng dụng dưới đây là một trang web mà cứ sau 5 giây nó sẽ tự động refresh. Màng hình đầu tiên Khi người dùng bấm vào nút Launch, trang này sẽ bắt đầu refresh và cứ sau 5 giây là trang nay tự động refresh và dữ liệu sẽ được load từ server hiện trên trang web của người dùng. Trang này đã refresh 2 lần
  16. 1.5.5 Displaying a Progress Bar Đôi lúc Client phải đợi Server xử lý lâu hay load dữ liệu lớn, người dùng phải đợi lâu, để biết được tiến trình thực hiên công việc tới đâu, và khi nào hoàn tất, ta dùng Progress Bar để hiển thị số % công việc thực hiện được. Màng hình đầu tiên Khi người dùng click vào nút Lunch, quá trình bắt đầu thực thi và hiện thị tỷ lệ % của quá trình cho người dùng thấy để tiện lợi cho việc theo dõi quá trình làm việc của hệ thống. quá trình làm việc được 35%
  17. Qua trình làm việc đã hoàn thành 1.5.6 Creating Tooltit Ứng dụng này phục vụ cho mục đích khi người dùng muốn xem thông tin cần thiết của một đối tượng, người dùng chỉ cần đưa chuột vào vị trí của đối tượng đó thì thông tin sẽ hiện ra. Màn hình đầu tiên
  18. Thể hiện thông tin của Pinehurst No. 2 khi đưa chuột vào vị trí củ nó. 1.5.7 Dynamically Updating a Web Page Khi thực hiện một thao tác nào đó thì hệ thống sẽ tự động cập nhật ngay và hiện thị trên cùng trang, mà không phải refresh. Ứng dụng dưới đây cho ta có thể thêm một nhân viên mới và nhân viên đó sẽ hiện ra ngay sau đó. Màn hình đầu tiên
  19. Khi thêm vào 2 nhân viên mới 1.5.8 Providing Autocomplete Tự động thêm vào input box những câu trả lời phù hợp với dữ liệu mà người dùng nhập vào.Nhờ vậy mà việc nhập dữ liệu nhanh hơn, dễ hơn và ít bị lỗi.
  20. 1.6. Framework : 1.6.1 Prototype Framework: 1.6.1.1. Định nghĩa: Framework Prototype là một framework Javascript hỗ trợ viết Ajax. 1.6.1.2. Các phương thức sử dụng để cập nhật dữ liệu từ Server: Ajax.Request() và Ajax.Update(). 1.6.1.2.1 Ajax.Request() cập nhật dữ liệu String: Các thông số của Request(): url: tên Server(Servelet hoặc JSP hoặc File XML) sẽ được gọi đến. asynchronous: true hay false , bất đồng bộ hay đồng bộ. method: "get" hay "post", hình thức gởi đến Server. parameters: "zipCode=" + zipCode, các tham số sẽ gởi đến Server : “tên tham số1=”+giá trị tham số1+ “&tên tham số2=”+giá trị tham số 2 + onSuccess: function(request) { a (); } nếu nhận response thành công thì gọi function này a()_ tênFunction, truyền 1 tham số: có thể là responseText hay responseXml () onFailure: function(request) { b (); } nhận response có lỗi thì gọi function này b()_tênFunction. 1.6.1.3 Cách sử dụng: Cần import thư viện prototype (file prototype.js): 1.6.1.3.1. Cập nhật bằng dữ liệu String: Server trả về String, Client cập nhật giá trị mới bằng cách hiện thực function assignProvince (). Client: .html function getPostCode(postCode) { new Ajax.Request("postcodevalidation", { asynchronous: true, method: "get", parameters: "postCode=" + postCode, onSuccess: function(request) { assignProvince(request.responseText); } }); } function assignProvince(data){} : giống Ví dụ 1 Server: StringReturn.java Object codeObj = postCodeMap.get(request.getParameter("postCode").trim());
  21. if(codeObj != null) out.println(codeObj.toString() +", "); else out.println(" ," + "Invalid Post Code"); 1.6.1.3.2. Cập nhật từ dữ liệu Javascript: Server trả về đoạn JavaScript để cập nhật giá trị mới cho các element cần thay đổi của Client, Client chỉ cần gọi function aval() của prototype để thực hiện đoạn Javascript đó. Có một điểm là Server phải biết rõ tất cả các element của Client. Ta cần hiện thực lại 2 tham số parameter và onSuccess như sau: parameters: "zipCode=" + zipCode + "&type=eval", thêm "&type=eval" onSuccess: function(request) { eval(request.responseText); }, gọi phương thức eval() của prototype thực hiện đoạn JavaScript do Server trả về. Client: .html function getPostCode(postCode) { new Ajax.Request("postcodevalidation", { asynchronous: true, method: "get", parameters: "postCode=" + postCode + "&type=eval", onSuccess: function(request) { eval(request.responseText); } }); } Server : JavasriptReturn.java public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); Object provinceObj = postCodeMap.get(request.getParameter("postCode").trim()); String province = "document.getElementById('province').value = "; String codeError = "document.getElementById('codeError').innerHTML = "; if(provinceObj != null) out.println(province + "'" + provinceObj.toString() + "';" + codeError + "''"); else out.println(province + "'';" + codeError + "'Invalid Post Code'"); } Pubilc void init(){} : giống ví dụ 1
  22. 1.6.1.3.3. Cập nhật từ dữ liệu HTML: Server trả về đoạn HTML sẽ được cập nhật cho các element cần thay đổi của Client. Có một điểm yếu giống như cập nhật bằng Javascript là Server phải biết rõ tất cả các element của Client. Làm lại ví dụ trên, nhưng đơn giản hơn là ta output kết quả ra dạng chuỗi, không cập nhật lên text field City và State vì đối tượng Update chỉ cập nhật tại thẻ Server trả về HTML và đặt HTML vào DOM qua property innerHTML Prototype làm điểm này rất đơn giản trên JavaScript. Bí quyết là ta cần chắc chắn rằng nội dung ta muốn thay đổi phải có thuộc tính id: Ta cần hiện thực lại hàm Update() lại tham số parameter và như sau: new Ajax.Updater(idCủaElement, url, { parameters : "zipCode=" + zipCode + "&type= html " , } Không cần tham số onSuccess. Ajax.Update() tạo request RHR, lấy output, ghi nó thành 1 element với id đã cho. Client: .html function getPostCode(postCode) { new Ajax.Updater("codeError", "postcodevalidation", { asynchronous: true, method: "get", parameters: "postCode=" + postCode + "&type=html", onFailure: function(request) { } }); } Server: HTMLReturn.java public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); Object provinceObj = postCodeMap.get(request.getParameter("postCode").trim()); String province = " "; if(provinceObj != null) out.print(codeError + " Province/City : " + provinceObj.toString() + " "); else out.print(codeError + "Invalid Post Code "); }
  23. 1.6.1.3.4. Ví dụ về cách dùng validate: Phát biểu bài toán: Xây dựng màn hình gồm các textField: Customer Name, Address, AccountNumber. Validate(kiểm tra) : Customer Name, Address, AccountNumber không rỗng và AccountNumber phải là một số. Cách giải quyết: gồm 3 cách: Cách 1: Kiểm tra tại server theo cách làm truyền thống_JSP-SERVLET (không có AJAX): Phía client: trang validationWithoutAjax.jsp. Phía server: lớp ValidationWithoutAjax.java. Theo cách làm này đảm bảo được tính bảo mật, phía client gửi request lên còn server xử lý và trả về kết quả. Ví dụ:  File validationWithoutAjax.jsp Customer Name: Address: AccountNumber:
  24. Nhập thông tin và nhấn nút Add Customer, gửi thông tin đến server : lớp ValidationWithoutAjax.java xử lý thông qua action=" validationwithoutajax " method="GET". Lớp ValidationWithoutAjax.java kiểm tra (validate) các textField Customer Name, Address và AccountNumber không rỗng và accountNumber phải là một số. Khi ValidationWithoutAjax.java trả kết quả, validationWithoutAjax.jsp thể hiện kết quả: " + result + " "); } %>  File ValidationWithoutAjax.java: public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); String name = request.getParameter("name"); String address = request.getParameter("address"); String account = request.getParameter("accountnumber"); if (name.length() == 0 || name == null || address.length() == 0 || address == null || account.length() == 0 || account == null) response.sendRedirect("validationWithoutAjax.jsp?error=Fill Full Fields"); else { try { Integer.parseInt(account); out.println("You successed"); } catch (Exception e) { response.sendRedirect("validationWithoutAjax.jsp? error=AccountNumber must be type a number"); } } }
  25. Kết quả trả về khi trường name, address và accountNumber rỗng . Hinh kết quả trả về khi trường name, address và accountNumber rỗng . Hình kết quả trả về khi AccountNumber không phải là một số. Tuy nhiên đối với server-side Validation, nhập xong nhấn nút gửi lên server xử lý rồi server trả kểt quả về, cứ mỗi lần nhập rồi gửi lên server xử lý, để có được feedback thì người dùng phải chờ làm mới (refresh) toàn bộ trang như vậy thì rất mất thời gian và chậm.Đồng thời trả về như vậy kèm theo hiện tượng chớp chớp.
  26. Cách 2: Kiểm tra tại client (dùng javascript): Chỉ xử lý phía client: trang clientValidationWithAjax.html Client-side validation thuận tiện cho người sử dụng.Bởi vì: họ có thể lấy được feedback ngay lập tức về sự chính xác của dữ liệu nhập vào, mà không phải đợi làm mới (refresh) lại toàn bộ trang.  trang clientValidationWithAjax.html: Customer Name: Address: AccountNumber: Trang này validate các trường name, address và accountNumber là một số. Thẻ : trả về dòng text lỗi màu đỏ ngay kế trường input thông qua id addressError hoặc nameError. Phương thức onblur() : Khi người dùng nhấp chuột sang vị trí khác hoặc tab thì sẽ biết được dữ liệu của mình nhập có chính xác hay không mà không cần đợi làm mới (refresh) lại toàn bộ trang, bằng cách gọi hàm validateField() và validateNumber(). validateField function validateField(tField) {
  27. if(tField.value == null || 0 == tField.value.length){ document.getElementById(tField.id + "Error").innerHTML = "Required Field"; } else{ document.getElementById(tField.id + "Error").innerHTML = ""; } } validateNumber function validateNumber(account){ if(account.value == null || 0 == account.value.length) document.getElementById("accountError").innerHTML = "Required Field"; else{ if(Number(account.value)) document.getElementById("accountError").innerHTML = ""; else document.getElementById("accountError").innerHTML = "must type a number"; } } Hình kết quả trả về khi tất cả các trường rỗng.
  28. Hình kết quả nhập đầy đủ thông tin name và address, nhập accountNumber không phải là một số. Tuy nhiên client-side validation thì vô dụng đối với người phát triển ứng dụng và rất tầm thường, mà một người sử dụng có thể làm hỏng client-side JavaScript, hoặc người sử dụng có thể bỏ qua toàn bộ HTML hồi đáp, hoặc có thể đưa ra những yêu cầu lừa đảo đối với hệ thống sử dụng Telnet. AJAX cho phép chúng ta kết hợp giữa client-side Validation và server-side Validation đối với những ứng dụng lớn. Cách 3: Dùng cho vấn đề kiểm tra dữ liệu (có AJAX): Phía client trang: validationWithAjax.html Phía server: Lớp ServerClientValidation.java Cách này kết hợp giữa server-side validation và client-side validation đảm bảo tính bảo mật và người dùng sẽ biết được dữ liệu của mình nhập vào có chính xác hay không, chỉ nhấp chuột sang vị trí khác, hoặc là tab mà không cần phải đợi refresh lại toàn bộ trang, tiện dụng cho người sử dụng. Bây giờ ta xây dựng ứng dụng có AJAX kết hợp giữa server-side validation và client-side validation cùng với sự hỗ trợ của gói Prototype của AJAX. Đầu tiên xây dựng trang validationWithAjax.html : + Gán validation vào sự kiện của các trường input.Sự kiện ở đây là onblur, sự kiện này thực hiên khi từ nó ta clicking đến bất kì vị trí nào khác hoặc dùng key tab.Gọi phương thức JavaScript validateField() và getZipData() thông qua onblur. Customer Name:
  29. Address: AccountNumber: + Viết phương thức gọi validation từ server kết hợp với Prototype library’s Ajax là Ajax.Updater và Ajax.Request.Nó khởi chạy với yêu cầu asynchronous, vượt qua đầy đủ thông tin cho việc validate field và update lại các element error message. Ajax.Updater(updater, url,{asynchronous: true, method: "get", parameters: }) updater: id được cập nhật khi có kết quả trả về từ server. url: đường dẫn đến server xử lý. Ajax.Request(url, {asynchronous: true, method: "get", parameters: "value" , onSuccess: function(request) { //doSthing}, onFailure: function(request) { //doSthing } }) Hàm validationField: function validateField(fieldName, updatedId) { var params = " fieldName =" + fieldName + "&value=" + $F(fieldname); new Ajax.Updater(updatedId, " validationwithajax ", { asynchronous: true, method: "get", parameters: params
  30. }); } + Tạo ra phương tiện validation được đặt trên server, dùng Servlet: ServerClientValidation public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String fieldName = request.getParameter("fieldName"); String value = request.getParameter("value"); if (fieldName.equals("accountnumber")) { if (value.length() == 0 || value == null) { out.println("Field Required"); } else { try { Integer.parseInt(value); out.println(""); } catch (Exception e) { out.println("Must type a number"); } } } else { if (null == value || 0 == value.length()) { out.println("Field required"); } else { out.println(""); } } }
  31. Hinh kết quả trả về khi tất cả các trường rỗng. Kết quả trả về khi trường name, address bỏ rỗng, accountNumber không phải là một số.
  32. 1.6.2. JSONRPC: 1.6.2.1. Định nghĩa JSON: JSON là một kiểu dữ liệu dự trên nền tảng cú pháp JavaScript cho Array litterals và Object litterals. Bởi vì dùng cú pháp JavaScript nên JSON có thể được định nghĩa trong JavaScript files và truy xuất không cần việc phân tích như XML Cú pháp đối tượng JSON được thể hiện như sau: Được bắt đầu bằng dấu ngoặc “{” Có một hoặc nhiều cặp thuộc tính/ giá trị (property/value), trong đó: thuộc tính (property) ngăn cách giá trị(value) của chúng bằng dấu hai chấm Các cặp property/ value ngăn cách với nhau bằng dấu phẩy. Cuối cùng được đóng bằng dấu ngoặc “}” Chú ý: Giá trị của mỗi thuộc tính có thể là: Chuỗi, mảng như [1,2,3], số, true, false, null, hay một đối tượng. ví dụ : var oCarInfo = { "availableColors" : [ "red", "white", "blue" ], "manufactory" : “Ford” } Truy xuất: alert(oCarInfo.availableColors[1]); //outputs "white" 1.6.2.2. Sử dụng JSONRPC để cập nhật bằng đối tượng: Mục đích Dùng JavaScript code để gọi hàm của đối tượng tại server bằng cách dùng JSON- RPC-JAVA và JSON-RPC cho client. Thay vì dùng XMLHttpRequest để gửi và nhận dữ liệu, thì nay JSON-RPC-JAVA đã giải quyết bằng cách ánh xạ (mapping) đối tượng Java thành một đối tượng JavaScript giúp người lập trình dễ dàng hơn trong việc xử lý dữ liệu được trả về từ server. Yêu cầu: Phía client: cần có file jsonrpc.js. Phía server: cần có file jsonrpc-cvs.jar. Các bước thực hiện:
  33. Các bước thực hiện: Bước 1: The JSONRPCServlet Trang servlet này là phần chuyển JSON-RPC-Java xử lý JSON-RPC request gửi bằng giao thức HTTP và gửi chúng tới JSONRPCBridge nằm trong HttpSession. Thêm JSONRPCServlet vào web.xml com.metaparadigm.jsonrpc.JSOnRPCServlet com.metaparadigm.jsonrpc.JSONRPCServlet com.metaparadigm.jsonrpc.JSONRPCServlet /JSON-RPC Bước 2: JSONRPCBridge: JSONRPCBridge giữ sự tham khảo để xuất ra đối tượng, mã hóa, và gửi phương thức mà client sẽ gọi đến đối tượng. JSONRPCBridge được đặt trong HttpSession với tên thuộc tính “JSONRPCBridge” để JSONServlet xác định vị trí. Đặt JSONBridge trong HttpSession vì lý do bảo mật. Có 2 cách dùng JSONRPCBridge cho JSP và cho Servlet. Đối với JSP: Gọi JSONRPCBridge chú ý scope = “session” Gọi lớp java chứa hàm mà client sẽ gọi tới. Đặt đối tượng vào JSONRPCBridge để client gọi tới. Từ lúc này client sẽ gọi đối tượng Java thông qua tên trong JSONRPCBridge mà ở đây là: myTestObject Đồng thời import 2 file jsonrpc.js(Để gọi đối tượng JSONRpcClient) và myapp.js (file này chứa các xử lý ở phía client)
  34. Đối với servlet: Đặt JSONRPCBridge vào HttpSession // Find the JSONRPCBridge for this session or create one // if it doesn’t exist. Note the bridge must be name “JSONRPCBridge” // in HttpSession for the JSONRPCServlet find it HttpSesson session = request.getSession(); MyTestObject myTestObject = new MyTestObject(); JSONRPCBridge json_bridge = null; json_bridge = (JSONRPCBridge) session.getAttribute(“JSONRPCBridge”); if(json_bridge = null){ json_bridge = new JSONRPCBridge(); session.setAttribute(“JSONRPCBridge”, json_bridge); } Đặt đối tượng vào JSONRPCBridge để client gọi tới json_bridge.registerObject(“myTestObject”, myTestObejct) Đồng thời import 2 file jsonrpc.js (Để gọi đối tượng JSONRpcClient) và myapp.js (file này chứa các xử lý ở phía client) out.println(“ ”) out.println(“ ”) Bước 3: File myapp.js có thể như sau: onLoad = function(){ try{ jsonrpc = new JSONRpcClient(“/ /JSON-RPC”); // Call a Java method on server var result = jsonrpc.myTestObject.myFunction(); alert(result); } catch(e){ alert(e); } } File myapp.js. trước hết phải gọi đối tượng JSONRpcClient với tên webapp của bạn đặt trước: var jsonrpc = new JSONRpcClient("/(your webapp name here)/JSON-RPC");
  35. Tiêp tục gọi phương thức của đối tượng Javatại server bằng tên đặt trong JSONRPCBridge, với cách gọi synchronous ta gọi như sau: jsonrpc.myTestObject.myFunction(); Chú ý: do cách gọi asynchronous, ta có thể thêm hàm trả về vào tham số thứ nhất của phương thức, mà ở đây là callback. Ví dụ myFunction() không có tham số, thì theo cách gọi asynchronous ta thêm hàm callback vào tham số thứ nhất do đó myFunction trở thành myFunction(callback) : jsonrpc.myTestObject.myFunction(callback); Và hàm callback có 2 biến: result (là kết quả trả về, cũng là một đối tượng JSON) và exception. Trong hàm đầu tiên ta kiểm tra có exception nào không nếu có thì hiện ra thông báo, sau đó mới xử lý đối tượng trả về mà ở đây là result: function callback(result, exception){ if(exception){alert(exception.message);} your code’s here } 1.6.2.3. Một số dạng đối tượng trao đổi dưới dạng JSONObject. Đối với Bean: Đối tượng JSON có dạng sau: “javaClass” : Tên của lớp Java, các dòng tiếp theo là thuộc tính và giá trị (property/value) của đối tượng. Truy xuất: vd : student.id // return SV1 var student = {“javaClass": "server.Student", "id": "SV1", "name": “Peter”, "age": 20 } Đối với List (ArrayList, LinkedList, Vector): Đối tượng JSON có dạng: “javaClass” tên của lớp java, và thuộc tính “list” có giá trị là array các phần tử của List. { "javaClass": "java.util.ArrayList", "list": [0, 1, 2, 3, 4] }
  36. Đối với Map (HashMap, TreeMap, LinkedHaspMap) : Đối tượng JSON có dạng: “javaClass” tên của lớp java, và thuộc tính “map” chứa các cặp key-value của map. { "javaClass": "java.util.HashMap", "map": {"foo key": "foo value"} } Đối với set (HashSet, TreeSet, LinkedHashSet): Đối tượng JSON có dạng: “javaClass” tên của lớp java, và thuộc tính “set” chứa các cặp key của set. Lưu ý: foo key ở đây chính là chuỗi trả về của hàm toString() của đối tượng được đặt vào set { "javaClass": "java.util.HashSet", "set": {"foo key": "foo key"} } 1.6.2.4. Ví dụ sử dụng JSON: Mô tả: Đây là ví dụ mô tả việc người dùng nhập vào một postcode trong textfield postcode, tự động trang web sẽ hiện ra tên tỉnh thành trong textfield province. Sau đây là các file cần thiết: File web.xml JSON APP com.metaparadigm.jsonrpc.JSONRPCServlet com.metaparadigm.jsonrpc.JSONRPCServlet com.metaparadigm.jsonrpc.JSONRPCServlet /JSON-RPC File PostCode.java package server; import java.io.Serializable; public class PostCode { private String postCode; private String province; public PostCode(String postCode, String province) {
  37. this.postCode = postCode; this.province = province; } public String getPostCode() { return postCode; } public String getProvince() { return province; } } File ManagePostCode.java package server; import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class ManagePostCode implements Serializable{ private List list = new ArrayList (); public ManagePostCode() { this.init(); } private void init() { list.add(new PostCode("04", "HaNoi")); list.add(new PostCode("061", "DongNai")); list.add(new PostCode("08", "TPHCM")); } public PostCode getPostCode(String code){  PostCode postCode = null; for (PostCode elm : list) { if(elm.getPostCode().equals(code)){ postCode = elm; return postCode; } } return postCode; } } : Hàm này dùng để tìm đối tượng PostCode có thuộc tính postcode giống tham số code bên ngoài nhập vào. File postcode.jsp     
  38. Enter Customer Data There are some postcode to test: 04, 08, 061, Customer Name: Post Code:  Province/ City: : Gọi đối tượng JSONRPCBridge, và đối tượng này có scope là session : Gọi đối tượng ManagePostCode : Đặt đối tượng ManagePostCode vào JSONRPCBridge với id là managepostcode : import file jsonrpc.js file này có chứa đối tượng JSONRpcClient dùng đẻ truy xuất các đối tượng Java tại server  import tile myapp.js file này dùng để xử lý các đối tượng server gửi về. Do người lập trình viết.  Khi người dùng lick ra ngoài textfield thì hàm getPostCode() sẽ được gọi. Hàm này được viết trong myapp.js. File myapp.js function getPostCode(code){ var jsonrpc = new JSONRpcClient("/ZipCodeJSON/JSON-RPC"); jsonrpc.managepostcode.getPostCode(callback,code);  } function callback(result, exception){ if(exception){alert(exception.message);} else { var province = result.province; document.getElementById("province").value = province;  } } : Tạo đối tượng JSONRpcClient(“/tên webapp/JSON-RPC”) để truy xuất các đối tượng tại server. Đối tượng này được định nghĩa trong jsonrpc.js. : gọi đối tượng ManagePostCode trong JSONRPCBridge thông qua id: managepostCode. Sau đó gọi hàm getPostCode() của đối tượng để tìm đối tượng PostCode có code trùng với code người dùng nhập vào. Vì theo cách goi asynchronous, nên có hàm callback ở vị trí tham số thư nhất, hàm trở thành getPostCode(callback) : xử lý đối tượng trả về. Lấy giá trị của thuộc tính province trong đối tượng JSON được gửi về và dặt vào trong textfield có id là province.
  39. 1.6.3 DWR: 1.6.3.1. Giới thiệu DWR là framework với mã nguồn(open source) giúp chúng ta làm việc với Ajax mà không phải thao tác trên đối tượng XMLHTTP Request. DWR gồm hai phần: code được sử dụng để kết nối đến server và code được sử dụng cho việc thể hiện dữ liệu được nạp từ server DWR mapping đối tượng java sang mã JavaScript. Vì vậy khi cài đặt ứng dụng chúng ta có thể gọi các phương thức của đối tượng java thông qua mã JavaScript. DWR giúp nạp động dữ liệu cho client từ server một cách dễ dàng, giúp hạn chế các thao tác mã cứng dữ liệu phía Client. 1.6.3.2 Các bước cấu hình ứng dụng với DWR framework: Mô tả ứng dụng: sử dụng DWR framework nạp dữ liệu động gồm các Postcode cho trang html từ server. Ứng dụng có thể được cài đặt trên môi trường Jbuilder hoặc Elipse và trước hết chúng ta cần có thư viện dwr.jar, bạn có thể tải file này ở trang Các bước cấu hình: File postcode.html Postcode Information List of Post code Postcodes:
  40. Post codes File PostCode.java public class PostCode { private static Map postcodeInfo; static{ postcodeInfo = Collections.synchronizedMap(new HashMap()); postcodeInfo.put("073","Tien Giang”); postcodeInfo.put("08","TPHCM”); postcodeInfo.put("O66", "Tay Ninh"); } public String[] getDesignerInfo(){ return (String[])postcodeInfo.keySet().toArray(new String[]{}); } public Map getPostCodeInfo() { return postcodeInfo; } public String getObject(String key){ return (String)postcodeInfo.get(key); } } Tạo file mapping dwr.xml và web.xml, hai file này được lưu trong cùng thư mục WEB-INF: File dwr.xml File web.xml www dwr-invoker uk.ltd.getahead.dwr.DWRServlet debug true dwr-invoker /dwr/*
  41. Tạo file javascript.js chứa các hàm tương tác với Server window.onload=function(){ setupSelect(); setupMap();}; function setupSelect(){ JsBean.getDesignerInfo(populate); } function populate(list){ DWRUtil.removeAllOptions("postcodes"); DWRUtil.addOptions("postcodes", list); } function setupMap(){ JsBean.getPostCodeInfo(setProdCodes); } //"data" is the JS object representation of a HashMap function setProdCodes(data){ var div = document.getElementById("postcodeInfo"); //remove old messages div.innerHTML=""; div.style.color="purple"; div.style.fontSize="0.9em"; var tmpText; for(var prop in data) { tmpText = prop + " :: "+ data[prop]; div.appendChild(document.createTextNode(tmpText)); div.appendChild(document.createElement("br")); } }  Một số điểm cần lưu ý khi cấu hình ứng dụng với DWR framework: Trang html, chúng ta cần lưu ý đến cách gọi các đối tượng javascript có sẵn. /ApplicationWithDWR là tên ứng dụng của chúng ta, tiếp theo đó là tên thư viện dwr và cuối cùng là tên đối tượng javascript mà chúng ta muốn lấy. Chúng ta cần đặt đúng tên file mapping là dwr.xml, nếu đặt không đúng tên hệ thống sẽ không chạy Một số hàm cần lưu ý: setupSelect(): load dữ liệu postcode cho trang html đươc thực thi thông qua hàm getDesignerInfo() của đối tượng java vừa được mapping sang mã javascript. setupMap(): load toàn bộ postcode cùng với tỉnh/thành phố cho trang html được thi hành thông qua hàm getPostCodeInfo()của đối tượng java vừa được mapping sang mã javascript.
  42. 1.7. Taglib Ajax: Ajax Tag Library là một tập các JSP Tag, nó được sử dụng nhằm đơn giản hóa cho việc dùng công nghệ Ajax. 1.7.1. FormUpDate 1.7.1.1. Chức năng: Giúp người dùng tự động cập nhật các trường còn lại của một form khi cho biết thông tin của một trường. Thường dùng để dùng cho các module như xem thông tin khách hàng, tính toán giá trị sau đó hiện kêt quả. 1.7.1.2 Cách sử dụng: Đối với người dùng: chỉ cần nhập một trường thông tin các trường còn lại sẽ tự đông hiện thị Đối với người lập trình: Bước 1: Cần có file: ajaxtags-1.2-beta1.jar, standard-1.1.2.jar và jstl.jar Bước 2: Trang jsp: Import hai file: prototype-1.4.0.js và ajaxtags-1.2-beta1.js Import taglib Ajax : Formupdate tag có dạng sau: baseUrl: Trang servlet ta muốn gọi đến source: id của textfield ma người dùng nhập vào, đê lấy value target: id của những textfield sẽ được hiển thị kết quả từ servlet, mỗi textfield sẽ cách nhau bời dấu phẩy. action: id của nút để bắt đầu gửi data tới trang servlet, tương ứng với hàm onClick. parameters: tên các tham số gửi tới servlet: vd: “id={textfield id}” parser: mặc định là ResponseHtmlParser preFunction: hàm được thực hiện trước khi bắt đầu thực hiện Ajax. postFunction: thực hiện sau khi response được gửi về. Bước 3: File servlet để xử lý phải extends BaseAjaxServlet. 1.7.1.3. Code demo: File formupdate.jsp: /js/prototype-1.4.0.js"> /js/ajaxtags-1.2-beta1.js">
  43. ${pageContext.request.contextPath} Update Form Field Tag Demo function initProgress() { Element.addClassName('mph', 'progressMeterLoading'); $('kph').value = ""; $('mps').value = ""; } Enter miles per hour and click Calculate Miles/Hour (mph): Kilometers/Hour (kph): Meters/Second (m/s) File FormUpdateServlet.java package server; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.ajaxtags.helpers.AjaxXmlBuilder; import org.ajaxtags.servlets.BaseAjaxServlet; public class FormUpdateServlet extends BaseAjaxServlet { public static final double MPH_TO_KPH = 1.609344; public static final double MPH_TO_MPS = 0.44704; public String getXmlContent(HttpServletRequest request, HttpServletResponse response) { double mph = 0, kph = 0, mps = 0; mph = Double.parseDouble(request.getParameter("mph")); System.out.println(mph); kph = mph * MPH_TO_KPH; mps = mph * MPH_TO_MPS; return new AjaxXmlBuilder() .addItem("kph", Double.toString(kph)) .addItem("mps", Double.toString(mps)) .toString(); } }
  44. 1.7.2 Auto-Complete: 1.7.2.1. Chức năng: Giúp người dùng nhập liệu dễ dàng hơn, thường được dùng để hổ trợ cho các module như contact, addressbook, search. 1.7.2.2. Cách sử dụng: Người sử dụng sẽ đưa vào một kí tự đầu tiên của tên đối tượng, nếu các đối tượng trong danh sách có kí tự đầu tiên bằng với kí tự này, thì các đối tượng này sẽ được load và được thể hiện bên dưới text input field. Người dùng chỉ cần click chọn đối tượng muốn đưa vào input text. 1.7.2.3. Code demo: File autocomplete.jsp Autocomplete Demo The ajax:autocomplete tag allows one to retrieve a list of probable values from a backend servlet (or other server-side control) and display them in a dropdown beneath an HTML text input field. The user may then use the cursor and ENTER keys or the mouse to make a selection from that list of labels, which is then populated into the text field. This JSP tag also allows for a second field to be populated with the value or ID of the item in the dropdown. You'll notice that an image is used to indicate a busy state while the XMLHttpRequest object is making it's request to the server-side. This is a bit of JavaScript/CSS trickery check the source to see how it's done. Enter Car Model Available values start with letters: 'A', 'C', 'E', 'F', 'M', 'R', 'T'
  45. Name: Make: File AutoCompleteServlet.java public class AutocompleteServlet extends BaseAjaxServlet { public String getXmlContent(HttpServletRequest request, HttpServletResponse response) throws Exception { String model = request.getParameter("model"); CarService service = new CarService(); List list = service.getModelsByName(model); // Create xml schema return new AjaxXmlBuilder().addItems(list, "model", "make").toString(); } }  URL mà client gọi xử lý từ server, URL này được qui định cụ thể trong file web.xml.  Class AjaxXmlBuilder là lớp được hổ trợ từ thư viện của java.
  46. 1.7.2. HTMLContent: 1.7.3.1 Chức năng: Giúp hiện thị thông tin của một thành đối tượng thông qua việc click vào link, radio và select. 1.7.3.2 Cách sử dụng: Lấy một ví dụ điển hình xây dựng màn hình gồm các chức năng link, radio, và select về các hãng xe hơi, ứng với mỗi hãng có các mô hình.Khi người dùng chọn hãng thì thể hiện các mô hình của hãng đó trên cùng trang. Màn hình lúc chưa chọn gì. Màn chọn radio hãng Honda. 1.7.3.3. Code demo : File htmlcontent.jsp.
  47. AJAX JSP Tag Library Examples /js/prototype- 1.4.0.js"> /js/ajaxtags-1.2-beta1.js"> HtmlContent Tag Demo | The ajax:htmlContent tag fills a content area (e.g., DIV tag) with an HTML fragment from another resource. You may find this tag useful for including blocks of information in a sidebar when the user clicks a link or form field. This tag is a more simplified approach to the ajax:portlet and ajax:tabPanel tags. Shown below are three different ways of executing the AJAX event: link, radio button, and select field.  Select by ANCHOR link.
  48. Select by RADIO option. Ford Honda Mazda Select by SELECT option. Select one Ford Honda Mazda Page loaded at: ${now} : được ajax hỗ trợ.Các tham số :  Hàm xử lý link anchor : baseUrl : đường dẫn gọi server xử lý.
  49. ${pageContext.request.contextPath}: chỉ vị trí của trang htmtlcontent.jsp. htmlcontent.view: trong trang web.xml qui định gọi tới server HtmlContentServlet xử lý. sourceClass: tên lớp của link anchor. target: vị trí thể hiện các mô hình ứng với id="modelDescription"  . parameters : tham số gửi đi, {ajaxParameter}: biến có sẵn của AJAX lấy giá trị người dùng chọn link hoặc radio button gán cho tham số make.  Hàm xử lý radio button.(tương tự link anchor)  Hàm xử lý select: Nhứng tham số baseUrl, source, target tương tự như trên. parameters: selmake tên của select , lấy giá trị mà người dùng chọn gán cho tham số make. eventChange: giá trị “change” mỗi khi mà người dùng chọn hãng thì thể hiện các mô hình của hãng đó. File HtmlContentServlet.java: import java.util.Date; import java.util.Iterator; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.ajaxtags.demo.Car; import org.ajaxtags.demo.CarService; import org.ajaxtags.servlets.BaseAjaxServlet; public class HtmlContentServlet extends BaseAjaxServlet { public String getXmlContent(HttpServletRequest request, HttpServletResponse response)throws Exception { String make = request.getParameter("make"); CarService service = new CarService(); List list = service.getModelsByMake(make); StringBuffer html = new StringBuffer(); html.append(" ").append(make.toUpperCase()). append(" Models "); for (Iterator iter = list.iterator(); iter.hasNext();) { Car car = (Car) iter.next(); html.append(" ").append(car.getModel()). append(" "); } html.append(" "); html.append(" "); html.append(" Last Updated: "); html.append(new Date()); html.append(" "); return html.toString(); } } Lớp HtmlContentServlet lấy tham số make trang htmlcontent.jsp gửi.
  50. Gọi phương thức getModelsByMake() của lớp CarService, trả về danh sách các mô hình ứng với tham số make nhận vào.Trả về cho client chuỗi danh sách các mô hình. 1.7.4 Tab Panel: 1.7.4.1. Chức năng: Giúp thể hiện nội dung đối tượng nhanh và dễ dàng hơn khi chuyển tab cho đối tượng, thường được áp dụng trong cây từ điển. Người dùng chỉ cần click vào các đối tượng, nội dung của từng đối tượng sẽ được thể hiện. 1.7.4.2. Code Demo: File tabpanel.jsp Tab Panel Tag Demo | The ajax:tabPanel tag provides a tabbed page view of content from different resources, typically other JSP or HTML pages. It expects the resource to return a valid HTML fragment, but not a complete page. Each panel is defined in a ajax:tab child tag with its own unique URL. The tab panel relies heavily on CSS to structure the panels themselves. The output is generated as an unordered list (<ul>) which works very nicely with the styles cataloged at . Tab Panel in Action <ajax:tab caption="Honda"
  51. baseUrl="${contextPath}/htmlcontent.view" parameters="make=honda"/> File HtmlContentServlet.java. public class HtmlContentServlet extends BaseAjaxServlet { public String getXmlContent(HttpServletRequest request, HttpServletResponse response) throws Exception { String make = request.getParameter("make"); CarService service = new CarService(); List list = service.getModelsByMake(make); StringBuffer html = new StringBuffer(); html.append(" ").append(make.toUpperCase()).append(" Mo dels "); for (Iterator iter = list.iterator(); iter.hasNext();) { Car car = (Car) iter.next(); html.append(" ").append(car.getModel()).append(" "); } html.append(" "); html.append(" "); html.append(" Last Updated: "); html.append(new Date()); html.append(" "); return html.toString(); } }