前言
在jsp的web項目中,很有可能會使用檔案上傳的功能。
把一個本地的檔案上傳到網頁伺服器的某個路徑下。
對於java 來說, 實現這樣功能的開源組件有很多, 比如較常用的commons-fileupload , 等等....
但是不管哪種組件,底層的原理應該都是一致的。 所以本系列從基本的方式和原理入手。
選擇檔案的按鈕標籤
<input type="file" />
這是一個HTML 的標籤, 所以不管是ASP,JSP, PHP 使用的方式都是一樣的。
此標籤放在form 的標籤裡面,顯示的效果是一個“選擇檔案”按鈕, 點擊之後會彈出一個檔案選擇的對話方塊。
此標籤在不同的流量器中顯示的效果可能會有不同(firefox和Chrome 的效果類似, 但是IE顯示的效果就有差異。 )
當要在某個form 中添加 file 的標籤時, form 的method 要設定成 “post”, enctype 設定成 "multipart/form-data",這樣的話,在點擊submit 提交時,
就會把檔案的內容以資料流的形式放入頁面的request 對象中。
配置類似:
<form action="BaseUpload.jsp" method="post" enctype="multipart/form-data">Please Select File: <input type="file" name="upload" size="16"><br><input type="submit" value="submit"></form>
form 中 action的配置
action作用是form 中的資料拋到哪處理,處理之後返回什麼。
對於jsp 而言, action 可以直接配置成 .jsp 的檔案,也可以配置成一個servlet;如果有使用spring , 還可以是一個 .do 或是 link 什麼的。
這裡為了方便,執行個體中先直接使用 .jsp 的方式。
執行個體
1. 這裡使用eclipse 開發, 所以先通過eclipse 建立一個動態Web 專案。
2. 在 WebContent 目錄下建立,選擇檔案的頁面 BaseUploadFile.jsp (尾碼名也可以是.html)
<!-- Add By oscar999 --><!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=UTF-8"><title>Insert title here</title></head><body><form action="BaseUpload.jsp" method="post" enctype="multipart/form-data">Please Select File: <input type="file" name="upload" size="16"><br><input type="submit" value="submit"></form></body></html>
2. 在同目錄下定義action 的jsp BaseUpload.jsp
<%@ page contentType="text/html;charset=UTF-8" %><%@ page import="java.io.*" %><%String sFileName = "tempfile.txt";String sFilePath = "D:\\temp\\upload\\files\\";ServletInputStream in = request.getInputStream();//FileOutputStream outputStream = new FileOutputStream(sFilePath+sFileName);PrintWriter pw = new PrintWriter( new BufferedWriter(new FileWriter(sFilePath+sFileName))); int i = in.read();while(i!=-1){pw.print((char)i);i = in.read();}pw.close();in.close();%>
這裡的動作很簡單, 就是把 request 的資訊寫入到一個txt 的檔案中, 來驗證一下是否如之前如之前所說,檔案的內容會放入request 對象中。
3. 打包,部署 。測試。 查看產生的txt 檔案內容
這裡上傳一個只有 "111" 這樣的簡單的 txt 文本。 在產生的檔案中內容如下:
------WebKitFormBoundaryGsj8EiAn9BkPrhAfContent-Disposition: form-data; name="upload"; filename="111.txt"Content-Type: text/plain111------WebKitFormBoundaryGsj8EiAn9BkPrhAf--
由此, 就可以從request 得到上傳檔案的內容, 通過流的方式就可以寫入到服務端了。
補充
1. 針對以上 action 的 BaseUpload.jsp , 也可以使用以下方式:
定義一個處理的java Bean, BaseUploadBean.java
/** * @author oscar999 * @date 2013-8-7 * @version V1.0 */package com.oscar999;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;public class BaseUploadBean {public void doUpload(HttpServletRequest request) throwsIOException {String sFileName = "D:\\temp\\upload\\files\\tempfile.txt";PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(sFileName)));ServletInputStream in = request.getInputStream();int i = in.read();while (i != -1) {pw.print((char) i);i = in.read();}pw.close();in.close();}}
這樣BaseUpload.jsp的內容就可以簡化成:
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="java.io.*" %>
<jsp:useBean id="TheBean" scope="page" class="com.oscar999.BaseUploadBean" />
<%
TheBean.doUpload(request);
%>
2. 另外, action 使用servlet 的方式
現在web.xml 配置servlet
<servlet> <servlet-name>FileUploadServlet</servlet-name> <servlet-class>com.oscar999.FileUploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FileUploadServlet</servlet-name> <url-pattern>/FileUploadServlet</url-pattern> </servlet-mapping>
然後在 dopost 方法中做類似的處理。