Upload file sử dụng Ajax Jquery và Apache Commons FileUpload

Chào mừng các bạn đã quay trở lại với thachleblog, như đã đề cập ở bài trước, sau khi đọc được file excel, mình cần tìm cách upload file lên server (server deploy app). Do đó, bài viết hôm nay mình sẽ giới thiệu với các bạn cách upload file sử dụng Apache Commons FileUpload. Qua bài viết này, các bạn sẽ hiểu được cách gửi một request có đính kèm 1 (hoặc nhiều) file lên server, đồng thời xử lý ghi file xuống server. Nào, chúng ta cùng bắt đầu nhé.

Để upload file lên server, việc đầu tiên ta cần sử dụng thẻ input file trong html để đính kèm file từ máy local vào request, tiếp theo là gửi request lên server.

<!DOCTYPE html>
<html lang="en">
  <head>
	<meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">
 
    <title>Dashboard Template for Bootstrap</title>
    <!-- Bootstrap core CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  </head>
  <body>
   <div class="container-fluid" >   	  
      <div class="row" style="margin-top: 50px;">      
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">     
          <h2 class="sub-header">Import file</h2>
		  <form id="code" method="post" enctype="multipart/form-data" class="form-horizontal">
			<div class="input-group">
				<input id="file-upload" type="file" name="file-upload">
			</div>
		  </form><br>
		  <button type="button" id="btn-import" class="btn btn-default">Upload</button>		  
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </body>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script type="text/javascript">  
	$(document).ready(function() {
		$("#btn-import").click(function() {
			var file = $('#file-upload').get()[0].files[0];
			var fileUpload = $('#file-upload').val();
			if(!file){
				alert("Vui lòng chọn file");
				return;
			}
			if (fileUpload && (fileUpload.indexOf('xlsx') === -1)) {
				alert("Vui lòng chọn file excel");
				return;
			}
 
			$.ajax({
				url: '/fileupload/ajax',
				type: 'POST',
				data: new FormData($('#code')[0]),
				processData: false,
				contentType: false
			}).done(function () {
				alert("Upload thành công");
			});
		});
	});	
  </script>
</html>
 
 
Code html demo cách sử dụng input file và gửi request  sử dụng Ajax Jquery

Lưu ý: ở đây mình sử dụng Ajax để gửi đến server request có đính kèm file excel sử dụng FormData, các bạn có thể tìm hiểu thêm về FormData tại đây. Chi tiết các bạn có thể đọc code ở trên (đính kèm 1 file).

Tiếp theo, ở phần server, chúng ta sẽ sử dụng Apache Commons FileUpload để xử lý request và lưu file xuống server

Các bạn có thể sử dụng maven hoặc download Apache Commons FileUpload tại đây. Lưu ý, để sử dụng Apache Commons FileUpload, cần tải thêm dependencies của nó là Apache Commons IO.

Implement:

package thach.le.fileupload;
 
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.eclipse.jetty.http.HttpStatus;
 
/**
 *
 * @author thachlp
 */
public class UploadFileController extends HttpServlet {
 
	private static final long serialVersionUID = 1L;
	private static final String UPLOAD_DIRECTORY = "/home/thachlp/Documents/";
 
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setStatus(HttpStatus.OK_200);
		// Check that we have a file upload request
		boolean isMultipart = ServletFileUpload.isMultipartContent(req);
 
		if (isMultipart) {
			// Create a factory for disk-based file items
			FileItemFactory factory = new DiskFileItemFactory();
			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);
			try {
				List<FileItem> fileItems = upload.parseRequest(req);
				String pathFile = "";
                                // loop for multi file
				for (FileItem item : fileItems) {
					if (!item.isFormField()) {
						pathFile = UPLOAD_DIRECTORY + File.separator + item.getName();
						item.write(new File(pathFile));
					}
				}
 
			} catch (Exception e) {
			}
		}
 
	}
}

Code demo cách xử lý request có đính kèm file và ghi file sử dụng Apache Commons FileUpload

Các bạn cần sửa lại đường dẫn thư mục cần lưu trữ file cho phù hợp.

Kết quả:

Upload file sử dụng Ajax Jquery và Apache Commons FileUpload

Link tải source code: https://github.com/thachlp/FileUpload
Tham khảo thêm: https://commons.apache.org/proper/commons-fileupload/using.html

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!