[教學]jsp Web的檔案上傳-FileUpload

Posted in Java, jsp, 程式 on 2010/3/22 by yku 瀏覽:690人次 — 4 回應

這是一個簡單的fileupload程式,把整個upload動作都包裝在UploadTool這個class裡,而在jsp裡再call此class來做檢查及上傳等動作。jar檔需放置WEB-INF/lib/裡,而程式complier後放置WEB-INF/classes/toolkie/裡。

首先需要二個第三方的jar檔

Apache FiluploadApache common io

都下載Binary的jar檔就可以了

再來利用下面的程式來進行上傳作業

UploadTool.java

package toolkie;

import java.io.File;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import java.util.*;

public class UploadTool {
  private int buffersize = 4096;
  private int SizeMax = 1024 * 1024;// 1Mbyte最大檔案大小
  private File tempfile = null;
  private String def_upload_dir = null;

  // 用來存parameter
  private Map map = null;
  private Map uploadlist = null;

  // 處始化時把給request把所有的值取出,存入map
  public UploadTool(HttpServletRequest request)
throws FileUploadException,
      UnsupportedEncodingException {

    map = new HashMap();
    uploadlist = new HashMap();

    // 建立一個以disk-base的檔案物件
    DiskFileItemFactory factory = new DiskFileItemFactory();

    // 初始化內容
    // 傳送所用的buffer空間
    factory.setSizeThreshold(buffersize);
    // The directory in which temporary files will be located.

    factory.setRepository(tempfile);

    // 建立一個檔案上傳的物件
    ServletFileUpload upload = new ServletFileUpload(factory);

    // 最大檔案大小
    upload.setSizeMax(SizeMax * 10);

    // 每一個Fileitem代表一個form上傳的物件內容ex input type="text"
    List items = null; // 會產生 FileUploadException
    // 把資料從request取出
    items = upload.parseRequest(request); // Parse the request

    Iterator iter = items.iterator();

    while (iter.hasNext()) {// 先把所有參數取得而不先write to file
      FileItem item = (FileItem) iter.next();
      // 一般文字欄位
      if (item.isFormField()) {
        map.put(item.getFieldName(), item.getString("Big5"));
        System.out.println("上傳檔案的其它參數:"
+ item.getFieldName() + "="
            + item.getString("Big5"));
      } else {// 上傳檔案欄位
        // or it's a file upload request

        if (item.getSize() > 0) {
          uploadlist.put(item.getFieldName(), item);
          System.out.println("上傳檔案:" + item.getFieldName());
        }
      }
    }
  }

  // 設定檔案上傳後存放的地方
  public void setUploadDir(String upload_dir) {
    this.def_upload_dir = upload_dir;
  }

  // 取得所有欄位,包含一般欄位及上傳的欄位
  public Map getAllParameter() {
    Map rvalue = new HashMap();
    rvalue.putAll(map);
    rvalue.putAll(uploadlist);
    return rvalue;
  }

  // 取得某一欄位的值,一般欄位
  public String getParameter(String FieldName) {
    if (map.containsKey(FieldName))
      return String.valueOf(map.get(FieldName));
    else
      return null;
  }

  // 取得某一欄位的值,上傳欄位
  public FileItem getUploadParameter(String FieldName) {
    if (uploadlist.containsKey(FieldName))
      return (FileItem) uploadlist.get(FieldName);
    else
      return null;
  }

  // 檢查上傳資料是否正確
  public String checkUpload() {
    Iterator iter = uploadlist.keySet().iterator();
    while (iter.hasNext()) {
      Object Name = iter.next();
      FileItem item = (FileItem) uploadlist.get(Name);
      String itename = item.getName();
      System.out.println("上傳的檔案為:" + itename);
      if (item.getSize() > SizeMax)
        return "檔案太大!";
    }
    return "";
  }

  // 開始上傳
  public String doUpload(FileItem item, String fileName) {
    String str = "";
    long sizeInBytes = item.getSize();
    // 碓認上傳資料是否有誤
    if (sizeInBytes > SizeMax)
      return "檔案太大!";

    if (sizeInBytes > 0) {

      int index = -1;
      String itename = null;
      if ((index = item.getName().lastIndexOf("\\")) != -1)
        itename = item.getName().substring(index,
            item.getName().length());
      else
        itename = item.getName();
      // 副檔名
      String formatName = itename.substring(
itename.length() - 4,
itename

          .length());

      fileName = (fileName + formatName).toLowerCase();

      System.out.println("上傳檔案檔案名稱:" + fileName);

      File uploadedFile = new File(def_upload_dir + fileName);
      // 會產生 Exception
      try {
        item.write(uploadedFile);

      } catch (Exception e) {
        System.out.println("上傳失敗!" + e.toString());
        str = "上傳失敗!";
      }
      // 會產生 Exception

    }
    return str;
  }

  // 是否存在此上傳欄位資料

  public boolean isExtUpload(String fileName) {
    return uploadlist.containsKey(fileName);
  }
}

這是整個程式最主要的範例

把所有可能會用到的上傳狀況及行為均寫入此Class裡

再來我們寫一個form來當上傳介面及另一個接收檔案的程式

form表單DemoFileUpload.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Insert title here</title>
</head>
<body>
<b>File Upload</b>
  <br>
  <form name="UploadForm"
enctype="multipart/form-data" method="post" action="doupload.jsp">
  檔案1<input type="file" name="File1" size="50" maxlength="20" />
<br>   

  檔案2<input type="file" name="File2" size="50" maxlength="20"/>
<br>

  文字<input type="text" name="textfield" size="50" maxlength="20"/>
<br> 

  <input type="submit" value="upload">
  </form>
</body>
</html>

實際使用doupload.jsp

<%@ page language="java" contentType="text/html; charset=BIG5"
    pageEncoding="BIG5"%>
    <%
    //把request傳入UploadTool裡
    toolkie.UploadTool upload = new  toolkie.UploadTool(request);
    %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Insert title here</title>
</head>
<body>
<%
//查詢是否錯誤
String msg = upload.checkUpload();
if(msg.length()>0)
{
  out.println(msg);
}
else
{
  //設定上傳路徑
  upload.setUploadDir(this.getServletContext().getRealPath("." ));
  out.println("上傳到此路徑:"
+this.getServletContext().getRealPath("." )+"<br/>");
  //取得文字檔
  out.println("文字欄位:"+upload.getParameter("textfield")+"<br/>");
  //開始上傳
  if(upload.isExtUpload("File1"))
    msg = upload.doUpload(upload.getUploadParameter("File1")
,"File1");
  if(msg.length()==0 && upload.isExtUpload("File2"))
    msg = upload.doUpload(upload.getUploadParameter("File1")
,"File2");

 
  if(msg.length()>0)
    out.println(msg);
  else
    out.println("上傳成功"+"<br/>");
 
}
%>

</body>
</html>

說明:

1.upload需要先設定到上傳的路徑為何

2.可以直接取得form其它非上傳欄位的值,用法跟request一樣->upload.getParameter("欄位名")

3.上傳指定的欄位檔案及更改其名稱->upload.doUpload(FileItem,"要變成的檔案名稱")

其中FileItem可以使用upload.getParameter("欄位名稱")

如上傳成功則不會有msg回傳,否則則會告知錯誤內容

ps.欄位名稱為傳送的form表單中元素的欄位名稱

 

以下是執行過程

1.選擇要上傳的檔案

2.按下upload後會告知檔案被上傳的路徑及文字欄位的內容及上傳成功與否

3.可以在上傳路徑裡看到二個剛才上傳的欄案,而名稱已重新命名了

4.可以在Console裡看到整個上傳過程

 

程式碼的說明均寫在裡面就不在詳述,有興趣的人可以看看

再來會再寫一篇如何使用Eclipse來執行jsp程式

將會使用上面的範例^^



Related Posts with Thumbnails

4 回應 to “[教學]jsp Web的檔案上傳-FileUpload”

  1. 1
    1255

    您好,我下載您的範例後執行後,eclipse會回報找不到CLASS
    我就加入了
    再執行一次變成了下面的錯誤
    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    javax.servlet.ServletException: java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItemFactory
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:268)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    請問我的問題是什麼原因產生的呢?
    謝謝

    [回應]

    yku Replay:

    這應該是您未在classpath裡加入需要的jar檔
    第三方的jar檔
    Apache Filupload及Apache common io
    你可以在文章一開始的地方取得連接,下載後解開裡面的jar
    然後開啟eclipse專案結點按右鍵properties->Java Build Path->Libraies 載入這些jar檔
    或著你可以把jar檔放到你載案目錄下的web-inf/lib目錄下,也有一樣的效果(如果是tomcat Server的話)

    [回應]

  2. 2
    weiham

    不好意思,打擾了,我參照你的程式碼,去實作檔案上傳的功能,
    但是在本機端測試可以成功將圖片上傳至
    C:\tomcat\webapps\Knowledge2\pic\

    但是在上傳至我自己的主機上運作,在上傳檔案之後仍出現 上傳成功
    但實際進入電腦裡面 pic的資料夾卻沒有檔案存在
    /var/lib/tomcat6/webapps/Knowledge/pic\

    upLoad_DIR=this.getServletContext().getRealPath("/")+"pic\\";
    這是我在上傳檔案的jsp頁面 所設定的路徑,

    因為沒有出現實際的錯誤訊息,所以才冒昧詢問一下,是否有相關的修正方向,可以提供給我參考

    不好意思,謝謝

    [回應]

    yku Replay:

    原始碼跟linux的環境是那一種可以給我一下嘛?
    我幫你架起來試看看^^
    有可能是你Linux給tomcat的權限不夠 有幾個地方要設
    一個是tomcat啟動的user
    一個是java的policy
    還有tomcat好像也要地方設
    建議你用下載的tomcat解壓縮來設定 可以參考我的文章
    用agt-get好像有這種問題...
    回答不知道是不是你想要的

    [回應]

留下您想說的話: