Load dữ liệu không đồng bộ với JQuery Ajax

Chào mừng các bạn đã quay trở lại với thachleblog, bài viết hôm nay mình sẽ demo cách load dữ liệu không đồng bộ dùng kỹ thuật JQuery Ajax với Java Servlet.

Giới thiệu

Ajax là viết tắt của Asynchronous JavaScript and XML, với Ajax, chúng ta có thể update web page mà không cần phải load page, request, receive data từ server sau khi page đã load, send data đến server trong chế độ background … thật power phải không, mình cũng chỉ mới làm với Ajax thời gian gần đây và khá là thích thú.

Load dữ liệu không đồng bộ với JQuery ajax

Lưu ý: load dữ liệu không đồng bộ (As sin chro nus) là kỹ thuật cho phép ta có thể load từng phần của web page mà không cần phải load cả nguyên page.

Bắt đầu

Chúng ta cần import các thư viện: Jetty, Hapax, Json cho demo này. Đầu tiên là file template danh sách sinh viên, ở đây mình sử dụng css boostrap để tạo bảng danh sách sinh viên:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
  8. <meta name="description" content="">
  9. <meta name="author" content="">
  10.  
  11. <title>Dashboard Template for Bootstrap</title>
  12. <!-- Bootstrap core CSS -->
  13. <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  14. </head>
  15. <body>
  16. <div class="container-fluid">
  17. <div class="row">
  18. <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
  19. <h2 class="sub-header">Danh sách sinh viên</h2>
  20. <div class="table-responsive">
  21. <button type="button" id = "btnAdd" class="btn btn-primary">
  22. <span class="glyphicon glyphicon-plus"></span>Tải thêm</button>
  23. <table id= "table" class="table table-striped">
  24. <tr>
  25. <th>#</th>
  26. <th>Tên</th>
  27. <th>Email</th>
  28. </tr>
  29. </thead>
  30. {{#list}}
  31. <tr>
  32. <td>{{id}}</td>
  33. <td>{{name}}</td>
  34. <td>{{email}}</td>
  35. </tr>
  36. {{/list}}
  37. </tbody>
  38. </table>
  39. </div>
  40. </div>
  41. </div>
  42. </div>
  43. </body>
  44. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  45. <script type="text/javascript">
  46. var index = 0;
  47. $("#btnAdd").click(function() {
  48. $.ajax({
  49. type: 'get',
  50. url: 'ajax/loadmore',
  51. data: {
  52. index : index
  53. },
  54. success: function (response) {
  55. $('#table').append('<tr><td>' + response.id + '</td><td>' + response.name + '</td><td>' + response.email + '</td><tr>');
  56. }
  57. });
  58. index += 1;
  59. });
  60.  
  61. </script>
  62. </html>

Ở đây mình sẽ dùng Ajax JQuery với cú pháp:

$.ajax({

name:value,

name:value,

});

Các tham số của cú pháp này các bạn có thể tham khảo tại đây, ở ví dụ này, mình chỉ demo cách lấy thêm dữ liệu cho danh sách sinh viên với button “Tải thêm”, mỗi khi user click button “Tải thêm”, sẽ có một  get request đến server và nhận về thêm 1 sinh viên mà không cần phải phải load lại page

Endpoint ajax để trả về data khi ajax gọi

  1. package thach.le.example;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import java.util.logging.Level;
  6. import java.util.logging.Logger;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import org.json.JSONException;
  11. import org.json.JSONObject;
  12. /**
  13.  *
  14.  * @author thachlp
  15.  */
  16. public class LoadMoreAjaxController extends HttpServlet {
  17. @Override
  18. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  19. try {
  20. List<Student> listStudent = new ArrayList<>();
  21. listStudent.add(new Student("10002", "Andy Le", "andyle@gmail.com"));
  22. listStudent.add(new Student("10003", "Peter Le", "peterle@gmail.com"));
  23.  
  24. String pram = req.getParameter("index");
  25. int index = Integer.valueOf(pram);
  26. if(index >= 2){
  27. index = 0;
  28. }
  29. JSONObject object = new JSONObject();
  30.  
  31. object.put("id", listStudent.get(index).getId());
  32. object.put("name", listStudent.get(index).getName());
  33. object.put("email", listStudent.get(index).getEmail());
  34.  
  35. resp.setContentType("application/json;charset=UTF-8");
  36. resp.getWriter().write(object.toString());
  37. } catch (JSONException ex) {
  38. Logger.getLogger(LoadMoreAjaxController.class.getName()).log(Level.SEVERE, null, ex);
  39. }
  40. }
  41. }

Endpoint Main để load dữ liệu khi chương trình bắt đầu, thật ra chúng ta có thể gộp chung 2 endpoint main và ajax và dùng jquery để lấy dữ liệu khi page load lần đầu, và load thêm khi click button, nhưng mình tách ra để các bạn dễ hiểu cách xử lý của endpoint ajax

  1. package thach.le.example;
  2. import hapax.TemplateLoader;
  3. import hapax.Template;
  4. import hapax.TemplateDataDictionary;
  5. import hapax.TemplateDictionary;
  6. import hapax.TemplateException;
  7. import hapax.TemplateResourceLoader;
  8. import java.io.IOException;
  9. import java.util.logging.Level;
  10. import java.util.logging.Logger;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.http.HttpServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import org.eclipse.jetty.http.HttpStatus;
  16. /**
  17.  *
  18.  * @author thachlp
  19.  */
  20. public class DashBoardController extends HttpServlet {
  21. @Override
  22. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  23. try {
  24. resp.setStatus(HttpStatus.OK_200);
  25. //TemplateLoader load resource
  26. TemplateLoader templateLoader = TemplateResourceLoader.create("thach/le/views/");
  27. //Template load file
  28. Template template = templateLoader.getTemplate("liststudent.xtm");
  29. //Use TemplateDictionary to put to xtm
  30. TemplateDictionary templeDictionary = new TemplateDictionary();
  31.  
  32. //Use TemplateDataDictionary to put data for section
  33. TemplateDataDictionary temp = templeDictionary.addSection("list");
  34. temp.setVariable("id", "" + 10001);
  35. temp.setVariable("name", "Thach Le");
  36. temp.setVariable("email", "thachle@gmail.com");
  37.  
  38. String data = template.renderToString(templeDictionary);
  39. resp.setContentType("text/html;charset=UTF-8");
  40. resp.getWriter().println(data);
  41. } catch (TemplateException ex) {
  42. Logger.getLogger(DashBoardController.class.getName()).log(Level.SEVERE, null, ex);
  43. }
  44. }
  45. }

Class Student

  1. package thach.le.example;
  2. /**
  3.  *
  4.  * @author thachlp
  5.  */
  6. public class Student {
  7. private String id;
  8. private String name;
  9. private String email;
  10. public Student(String id, String name, String email) {
  11. this.id = id;
  12. this.name = name;
  13. this.email = email;
  14. }
  15. public String getId() {
  16. return id;
  17. }
  18. public void setId(String id) {
  19. this.id = id;
  20. }
  21. public String getName() {
  22. return name;
  23. }
  24. public void setName(String name) {
  25. this.name = name;
  26. }
  27. public String getEmail() {
  28. return email;
  29. }
  30. public void setEmail(String email) {
  31. this.email = email;
  32. }
  33. }

Class Main để start Server Jetty

  1. package thach.le.example;
  2. import org.eclipse.jetty.server.Server;
  3. import org.eclipse.jetty.servlet.ServletContextHandler;
  4. /**
  5.  *
  6.  * @author thachlp
  7.  */
  8. public class Main {
  9. public static void main(String[] args) throws Exception {
  10. Server server = new Server(7070);
  11. ServletContextHandler handler = new ServletContextHandler(server, "/*");
  12. handler.addServlet(DashBoardController.class, "/dashboard");
  13. handler.addServlet(LoadMoreAjaxController.class, "/ajax/loadmore");
  14. server.start();
  15. }
  16. }

Và kết quả cuối cùng, chúng ta sẽ có chương trình demo cách load dữ liệu động sử dụng ajax jquery, table sẽ thêm 1 record mới với dữ liệu trả về từ server thông qua ajax:

Vừa rồi là phần demo sử dụng JQuery ajax để load dữ liệu không đồng bộ. Jquery, ajax. Mình sẽ tiếp tục chia sẻ ở các bài sau.

Rất mong nhận được ý kiến đóng góp của các bạn. Mọi thắc mắc vui lòng comment bên dưới, mình sẽ follow.

Thân!

Sử dụng text template trong Java với hapax2

Chào mừng các bạn đã quay trở lại với thachleblog. Mặc dù dạo này khá là bận rộn nhưng mình sẽ vẫn giữ tiến độ 2 blog/tuần. Thường các ngày trong tuần sẽ có một bài và bài còn lại vào cuối tuần. Bài viết hôm nay mình sẽ giới thiệu với các bạn một text template library trong Java đó chính là hapax.

Text template là gì? Hapax được sử dụng như thế nào? Rất là đơn giản, chúng ta cùng bắt đầu nhé.

text template trong java với hapax2

Sơ đồ mô tả vai trò của text template (Hapax)

Giới thiệu

Hapax là một implementation của Google Ctemplate. Hapax được sử dụng để truyền dữ liệu động vào cho html tĩnh thông qua Java. Ưu điểm của hapax là khá nhẹ và đơn giản. Chỉ làm việc trên html nên không phụ thuộc vào web framework, có thể sử dụng trong servlet, scripting languages và ứng dụng server – side…

Nói đến đây mà các bạn vẫn không hiểu hapax để làm gì thì các bạn nên qua thẳng phần ví dụ trước khi xem phần đặc điểm nhé 😀

Đặc điểm

Hapax hiểu đơn giản là một dạng html nhưng có khả năng truyền dữ liệu động thông qua Java.

Hapax cung cấp các tính năng:

  • Variable: dữ liệu được truyền vào html thông qua cú pháp {{variable}} hoặc {{=variable}}
  • Comment: comment được sử dụng bằng cú pháp {{!…t}}
  • Section: được hiểu như 1 phần của trang web (thao tác addSection) hoặc sử dụng như vòng lặp, cú pháp {{#sectionName}} … {{/sectionName}}
  • Include: đơn giản như include thư viện trong java script, những phần chung ta tách ra và include vào từng file với cú pháp {{>name}}

Ví dụ

Các bạn có thể tải hapax2 library về tại đây

File book.xtm (đổi định dạnh từ file html đổi định dạng để hapax đọc được). Mình có 1 table danh sách các book được truyền vào từ Java

  1. <!DOCTYPE html>
  2. table {
  3. font-family: arial, sans-serif;
  4. border-collapse: collapse;
  5. width: 100%;
  6. }
  7.  
  8. td, th {
  9. border: 1px solid #dddddd;
  10. text-align: left;
  11. padding: 8px;
  12. }
  13.  
  14. tr:nth-child(even) {
  15. background-color: #dddddd;
  16. }
  17. </head>
  18. <tr>
  19. <th>Id</th>
  20. <th>Name</th>
  21. <th>Category</th>
  22. </tr>
  23. {{#book}}
  24. <tr>
  25. <td>{{id}}</td>
  26. <td>{{name}}</td>
  27. <td>{{category}}</td>
  28. </tr>
  29. {{/book}}
  30. </body>
  31. </html>

Hapax2Example class

  1. /*
  2.  * To change this license header, choose License Headers in Project Properties.
  3.  * To change this template file, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */
  6. package thach.le.hapax2.example;
  7.  
  8. import hapax.Template;
  9. import hapax.TemplateDataDictionary;
  10. import hapax.TemplateDictionary;
  11. import hapax.TemplateException;
  12. import hapax.TemplateLoader;
  13. import hapax.TemplateResourceLoader;
  14.  
  15. /**
  16.  *
  17.  * @author thachlp
  18.  */
  19. public class Hapax2Example {
  20.  
  21. /**
  22. * @param args the command line arguments
  23. * @throws hapax.TemplateException
  24. */
  25. public static void main(String[] args) throws TemplateException {
  26. //TemplateLoader load resource
  27. TemplateLoader templateLoader = TemplateResourceLoader.create("thach/le/view/");
  28. //Template load file
  29. Template template = templateLoader.getTemplate("book.xtm");
  30. //Use TemplateDictionary to put to xtm
  31. TemplateDictionary templeDictionary = new TemplateDictionary();
  32. for (int i = 1; i <= 2; i++) {
  33. //Use TemplateDataDictionary to put data for section
  34. TemplateDataDictionary temp = templeDictionary.addSection("book");
  35. temp.setVariable("id", "" + i);
  36. temp.setVariable("name", "Life of PI");
  37. temp.setVariable("category", "Novel");
  38. }
  39. String data = template.renderToString(templeDictionary);
  40.  
  41. System.out.println(data);
  42.  
  43. }
  44.  
  45. }

Kết quả 

Code html

  1. <!DOCTYPE html>
  2. table {
  3. font-family: arial, sans-serif;
  4. border-collapse: collapse;
  5. width: 100%;
  6. }
  7. td, th {
  8. border: 1px solid #dddddd;
  9. text-align: left;
  10. padding: 8px;
  11. }
  12. tr:nth-child(even) {
  13. background-color: #dddddd;
  14. }
  15. </head>
  16. <tr>
  17. <th>Id</th>
  18. <th>Name</th>
  19. <th>Category</th>
  20. </tr>
  21. <tr>
  22. <td>1</td>
  23. <td>Life of PI 1</td>
  24. <td>Novel</td>
  25. </tr>
  26. <tr>
  27. <td>2</td>
  28. <td>Life of PI 2</td>
  29. <td>Novel</td>
  30. </tr>
  31. </body>
  32. </html>

Các bạn nếu có hứng thú thì đọc code, chỗ nào không hiểu mình sẽ giải thích nhé. Hoặc các bạn cũng có thể xem qua ở mức over view để hiểu về nguyên tắc hoạt động của hapax cũng như các ứng dụng java template chung, sau đó có thể sử dụng các framework khác dễ dàng.

Vừa rồi là phần trình bày của mình về hapax. Mình sử dụng hapax này và thấy khá hiệu quả. Tuy nhiên do đã hết được support từ 2011 nên document không nhiều. Hy vọng qua bài viết này các bạn có thể hiểu và sử dụng hapax (dự án mình làm đang xài cái này, khá là nhẹ và nhanh).

Hẹn gặp lại các bạn ở các bài viết sau.

Tham khảo thêm: https://code.google.com/archive/p/hapax2/wikis/Language.wiki