Bộ sưu tập

Upload File với Struts 2


https://codersontrang.com/2014/09/16/upload-file-trong-struts-2/

Bài viết trước đã hướng dẫn cách tạo một ứng dụng web cơ bản bằng framework Struts2, để tiếp tục loạt bài viết về Struts2, bài viết này sẽ hướng dẫn cách để upload file trong ứng dụng web sử dụng framework này.

Tạo một Maven web project trong Eclipse IDE có cấu trúc như hình dưới đây:

codersontrang_struts2_uploadfile_1

pom.xml

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  <groupId>codersontrang.example</groupId>  
  <artifactId>struts2-file-upload</artifactId>  
  <packaging>war</packaging>  
  <version>0.0.1-SNAPSHOT</version>  
  <name>struts2-file-upload Maven Webapp</name>  
  <url>http://maven.apache.org</url>  
  <dependencies>  
    <dependency>  
           <groupId>org.apache.struts</groupId>  
           <artifactId>struts2-core</artifactId>  
           <version>2.3.16.3</version>  
       </dependency>   
  </dependencies>  
  <build>  
   <finalName>struts2-file-upload</finalName>  
  </build>  
 </project>  

File pom.xml khai báo các dependencies sử dụng trong ứng dụng, phiên bản của struts2 sử dụng trong ví dụ này là 2.3.16.3, ta có thể thấy các dependecies đi kèm theo với nó sẽ như hình dưới đây

codersontrang_struts2_uploadfile_7

Để sử dụng struts ta không quên khai báo trong web.xml như dưới đây:

web.xml

 <!DOCTYPE web-app PUBLIC  
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
  "http://java.sun.com/dtd/web-app_2_3.dtd" >  
 <web-app>  
       <display-name>Struts 2 File Upload</display-name>  
       <filter>   
             <filter-name>struts2</filter-name>   
             <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>   
       </filter>   
       <filter-mapping>   
             <filter-name>struts2</filter-name>   
             <url-pattern>/*</url-pattern>   
       </filter-mapping>   
 </web-app>  

struts.xml

 <?xml version="1.0" encoding="UTF-8" ?>   
  <!DOCTYPE struts PUBLIC   
  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"   
  "http://struts.apache.org/dtds/struts-2.0.dtd">   
  <struts>   
    <constant name="struts.custom.i18n.resources" value="message" />  
    <package name="my-package" namespace="/upload" extends="struts-default">   
       <action name="index" class="struts2.actions.FileUploadAction" method="index">   
         <result name="success">/WEB-INF/jsp/file-upload/index.jsp</result>   
       </action>   
       <action name="perform-upload" class="struts2.actions.FileUploadAction" method="performUpload">  
         <interceptor-ref name="fileUpload">  
           <param name="maximumSize">1000000</param>  
           <param name="allowedTypes">  
             image/png,video/*  
           </param>  
           <param name="allowedExtensions">  
             .doc,.jar,.png,.mp4  
           </param>  
         </interceptor-ref>   
         <interceptor-ref name="defaultStack"></interceptor-ref>  
         <result name="success">/WEB-INF/jsp/file-upload/index.jsp</result>  
         <result name="input">/WEB-INF/jsp/file-upload/index.jsp</result>   
         <result name="error">/WEB-INF/jsp/file-upload/index.jsp</result>   
       </action>   
    </package>   
  </struts>   

File struts.xml định nghĩa ra các action của ứng dụng, ở đây ta có 2 action là

  • /upload/index: cho phép người dùng truy cập vào trang web để thực hiện việc upload file
  • /upload/perform-upload: thực hiện việc upload file

Ở struts2, việc upload file được đơn giản hóa đi rất nhiều bằng việc được cung cấp sẵn một interceptor có tên là fileUpload, interceptor là một khái niệm trong struts có thể hiểu nôm na là một đoạn mã thực thi trước khi thực hiện một action cụ thể. Ở đây, trước khi thực hiện action /perform-upload, các thông tin từ phía người dùng sẽ phải đi qua fileUpload interceptor trước, fileUpload interceptor của struts2 sẽ thực hiện copy file upload vào một thư mục tạm, sau đó sẽ thực hiện kiểm tra tính hợp lệ của file đó, nếu có lỗi sẽ trả mã lỗi về phía người dùng. Trong trường hợp file upload lên là một file hợp lệ, thì action trong trường hợp này là /perform-upload sẽ được tiếp tục thực thi.

fileUpload interceptor cho phép người lập trình viên quy định một số quy tắc cho việc upload file như là giới hạn kích thước của file, chỉ được upload một số kiểu file nhất định qua các tham số maximumSize, allowedTypes, allowedExtensions. Như khai báo ở trên, ví dụ của chúng ta chỉ cho phép upload các file loại image/png, video/*, .doc, .jar, .png, .mp4 và yêu cầu file upload lên có kích thước không vượt quá 1000000 bytes.

/file-upload/index.jsp

 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
   pageEncoding="ISO-8859-1"%>  
 <%@taglib uri="/struts-tags" prefix="s"%>   
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
 <html>  
 <head>  
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
 <title>Struts File Upload</title>  
 </head>  
 <body>  
      <h3>Choose File & Upload</h3>  
      <s:form action="/upload/perform-upload" method="post" enctype="multipart/form-data" theme="simple">  
           <s:file name="inputFile"   
                     title="Choose File to Upload"  
                     accept=".doc,.jar,image/png,video/*"   
                     />  
           <button>Upload</button>  
           <br/><br/>  
           <s:if test="successMsg != null">  
                
</s:if> <s:fielderror cssStyle="color:red;"></s:fielderror> </s:form> </body> </html>

Trang index.jsp sẽ hiển thị cho người dùng một form để thực hiện upload file. Kiểu dữ liệu gửi lên server sẽ được mã hóa theo kiểu multipart/form-data

FileUploadModel.java

 package struts2.model;  
 import java.io.File;  
 public class FileUploadModel {  
      private File inputFile;  
      private String inputFileFileName;  
      private String inputFileContentType;  
      private String successMsg;  
      private String errorMsg;  
      public String getInputFileFileName() {  
           return inputFileFileName;  
      }  
      public void setInputFileFileName(String inputFileFileName) {  
           this.inputFileFileName = inputFileFileName;  
      }  
      public String getInputFileContentType() {  
           return inputFileContentType;  
      }  
      public void setInputFileContentType(String inputFileContentType) {  
           this.inputFileContentType = inputFileContentType;  
      }  
      public String getSuccessMsg() {  
           return successMsg;  
      }  
      public void setSuccessMsg(String successMsg) {  
           this.successMsg = successMsg;  
      }  
      public String getErrorMsg() {  
           return errorMsg;  
      }  
      public void setErrorMsg(String errorMsg) {  
           this.errorMsg = errorMsg;  
      }  
      public File getInputFile() {  
           return inputFile;  
      }  
      public void setInputFile(File inputFile) {  
           this.inputFile = inputFile;  
      }  
 }  

Model là nơi sẽ nhận thông tin gửi lên từ phía người dùng, trong trường hợp này là thông tin về file được upload. Một trong những công việc của fileUpload interceptor nữa là mapping thông tin của file upload vào trong struts model. Các thông tin này bao gồm một đối tượng kiểu java.io.File biểu diễn nội dung file upload đang được lưu vào thư mục tạm, kiểu nội dung (content type) của file, và tên của file đang được upload. Trong ví dụ này các thông tin sẽ được lưu tương ứng vào 3 thuộc tính inputFile, inputFileFileName, inputFileContentType. Việc mapping sẽ được làm tự động, chúng ta chỉ việc đặt tên các thuộc tính trong model theo một chuẩn tương ứng là {nameInView}, {nameInView}FileName, {nameInView}ContentType (trong ví dụ {nameInView} = “inputFile” tương ứng với thẻ <s:file name="inputFile" ... /> trong trang index.jsp ở trên)

FileUploadAction.java

 package struts2.actions;  
 import java.io.File;  
 import org.apache.commons.io.FileUtils;  
 import struts2.model.FileUploadModel;  
 import com.opensymphony.xwork2.ActionSupport;  
 import com.opensymphony.xwork2.ModelDriven;  
 import com.opensymphony.xwork2.ValidationAware;  
 public class FileUploadAction extends ActionSupport implements ModelDriven<FileUploadModel>, ValidationAware{  
      FileUploadModel model = new FileUploadModel();  

      public String index(){  
           return SUCCESS;  
      }  

      public String performUpload(){  
           try{  
                File f = model.getInputFile();  
                if(f == null){  
                     addFieldError("inputFile", "The input file is required");  
                     return INPUT;  
                }  

                String fileName = model.getInputFileFileName();  
                String contentType = model.getInputFileContentType();  
                FileUtils.copyFile(f, new File("D:\\StrutsUpload\\" + fileName));  
                model.setSuccessMsg("Upload success ! File name: "+fileName+", File content type: "+contentType+", File size: "+f.length() + " byte(s).");  
                return SUCCESS;  
           }catch(Exception e){  
                return ERROR;  
           }  
      }  

      public FileUploadModel getModel() {  
           return model;  
      }  
 }  

Action index() chỉ đơn giản là đưa người dùng đến với trang thực hiện việc upload. Khi thông tin về file upload đi qua fileUpload interceptor và mọi thông tin hợp lệ thì quá trình thực hiện được tiếp tục với action performUpload(). Trong action này, ta kiểm tra nếu người dùng thực sự đã nhập một file để upload hay chưa. Nếu đã nhập một file thì thực hiện việc copy file được upload lên từ thư mục tạm vào thư mục mà ta mong muốn trên server là D:\\StrutsUpload\

Chạy ví dụ trên server Apache Tomcat 7, truy cập theo đường dẫn /upload/index sẽ đưa người dùng đến form để thực hiện việc upload như sau

codersontrang_struts2_uploadfile_2

Các trường hợp dữ liệu không hợp lệ sẽ được server gửi trở lại cùng với lời nhắn tương ứng:

Người dùng không nhập file nào cả và bấm upload
codersontrang_struts2_uploadfile_3

Người dùng upload một file lớn hơn kích thước cho phép
codersontrang_struts2_uploadfile_4

Người dùng upload một loại file không được cho phép
codersontrang_struts2_uploadfile_5

Trong trường hợp nhập một file có kích thước quá giới hạn hoặc không thuộc kiểu cho phép thì struts2 đang trả về lời nhắn mặc định. Ta có thể thay đổi những lời nhắn này để chúng trở nên ý nghĩa và thân thiện với người dùng hơn bằng cách override chúng trong file message.properties

message.properties

 struts.messages.error.uploading                       = Error happened when uploading  
 struts.messages.error.file.too.large                 = Your file is too large  
 struts.messages.error.content.type.not.allowed       = The content type is not allowed   
 struts.messages.error.file.extension.not.allowed     = The file type is not allowed  

Khi nhập vào một file hợp lệ và bấm upload, server sẽ trả về lời nhắn thành công kèm theo thông tin về file vừa được upload trên server như tên file và kiểu file và kích thước của nó

codersontrang_struts2_uploadfile_6

Kiểm tra trong thư mục D:\\StrutsUpload\ ta thấy file đã được upload vào thư mục này
codersontrang_struts2_uploadfile_8

Chú ý:
1. Trong trường hợp muốn upload nhiều file lên server cùng một lúc, ta chỉ việc thêm nhiều control <s:file/> vào trong file jsp với việc đảm bảo rằng các control này phải cùng tên. Tiếp đó trên model sẽ sửa để chứa một mảng kiểu File (hoặc một List), một mảng kiểu String chứa tên file, một mảng kiểu String chứa kiểu file. Việc thao tác với các file upload sẽ được thực hiện dựa trên các mảng này.

2. Mặc định struts2 giới hạn kích thước của file upload là 2097152 bytes (2MB). Để thay đổi giới hạn này bằng cách thêm cấu hình trong struts.xml như sau

<constant name="struts.multipart.maxSize" value="2000000000" />

Với cấu hình như trên ta có thể upload file có kích thước xấp xỉ 2GB.

3. Ta có thể cấu hình để thay đổi thư mục lưu file upload tạm thời như sau

<constant name="struts.multipart.saveDir" value="D:\StrutsUpload\temp"/>

Good luck!

Advertisements
By Coder Sơn Trang Posted in Struts2

One comment on “Upload File với Struts 2

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất /  Thay đổi )

Google photo

Bạn đang bình luận bằng tài khoản Google Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )

Connecting to %s