201112012210jQuery File Upload - 非同步檔案上載(Server端REST收取檔案)

在上一篇裡頭主要是有關使用jQuery File Upload元件上載檔案時偏向網頁前端的做法,這篇就來記錄一下有關後端REST方式收取檔案的方法。

用到的相關jar檔主要有:

asm-3.1.jar, jersey-core-1.6.jar, jersey-server-1.6.jar, commons-fileupload-1.2.2.jar, commons-io-1.2.jar, gson-1.6.jar

首先在tomcat專案裡頭的web.xml要加入以下內容:

<servlet>
<servlet-name>REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>test</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>REST Service</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>

接著先寫一個callback時要用到的bean:FileUploadResultBean.java

主要元素有name, size, url, thumbnail_url, delete_url, delete_type, fieldName...等,如有其他特殊用途的欄位可行加入。

再來就是主要處理檔案的部分:FileHandler.java

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

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 com.google.gson.Gson;

import com.bean.FileUploadResultBean;

@Path("file/")
public class FileHandler{
@POST
@Path("upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public Response fileUpload(@Context HttpServletRequest request){
String dirPath = "";
String filePath = "/tmp/";
String fileName = "tmp_"+(int)(Math.random()*100000);
FileUploadResultBean res = new FileUploadResultBean();

if(ServletFileUpload.isMultipartContent(request)){
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("utf-8"); //中文檔名問題
List<FileItem> items = null;
try{
items = (List<FileItem>)upload.parseRequest(request);
}catch(Exception e){
e.printStackTrace();
}
if(items!=null){
Iterator<FileItem> iter = items.iterator();
while(iter.hasNext()){
FileItem item = iter.next();
String oriFileName = "";
String fileType = "";
if(!item.isFormField()&&item.getSize()>0){
//dir exist?
File dir = new File(filePath+dirPath);
if(!dir.isDirectory()){
try{
if(!dir.mkdir()){
System.out.println("can't create directory, dirPath = "+dirPath);
}
}catch(Exception e){
e.printStackTrace();
}
}
                        oriFileName = item.getName();						
fileType = oriFileName.substring(oriFileName.lastIndexOf(".")+1,oriFileName.length());
try{
item.write(new File(new StringFilter().filter(filePath+dirPath+"/"+
fileName+"."+fileType)));
}catch(Exception e){
e.printStackTrace();
}
res.setUrl("/tmp/"+dirPath+"/"+fileName+"."+fileType);
res.setThumbnail_url("");
res.setError("0");
res.setFieldName("fName[]");
res.setSize(item.getSize());
res.setName(fileName+"."+fileType);
res.setDelete_type("DELETE");
res.setDelete_url("unknow");
res.setOriFileName(oriFileName);
}else{
if(item.getFieldName().equals("dirPath")){
dirPath = item.getString();
}
}
}
}else{
System.out.println("items is null!!!");
}
}
Gson gson = new Gson();
String gsonStr = gson.toJson(res);
ResponseBuilder builder = Response.ok(gsonStr);
return builder.build();
}
}

這個範例主要就是一個檔一個檔案接收,大致就是這樣寫,如果要一次上載多個檔案就要改一下最後return的部份,把多個bean用array的方式輸出回去iframe.jsp那個檔裡頭,且上傳的input file欄位要加入multiple屬性。

至於刪除的功能呢...因為有點懶,其實只要在前端已上載的檔案清單檔名後按垃圾桶按鈕,即可把該列刪除,換句話說,使用test.jsp裡的getFileNames()就不會抓到該檔名,雖然實際上那個檔案還是已經上傳到server端了,但只要在complete.jsp裡頭收參數後進行檔案搬移與刪除就可以達到刪除的目的嚕。

以上有部份的code是參考自以下網址:

http://iambigd.blogspot.com/2011/07/jquery-plugin-jquery-file-upload.html

 

回應