web專案利用apache的DiskFileItemFactory和ServletFileUpload上傳圖片
最近在做java的web專案時,遇到圖片上傳此功能,我是利用apache提供的第三方jar來實現的
一:首先需要引用以下兩個jar包
二:<form>
表單要設定屬性enctype="multipart/form-data"
<form name="itemForm" target="_self" id="itemForm" method="post" action="servlet/item/FileUploadServlet" enctype="multipart/form-data">
<input type="hidden" name="itemNo" value="<%=item.getItemNo() %>">
<div align="center">
<table width="95%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="26"><div align="right">物料名稱:&bsp; </div></td>
<td><%=item.getItemName() %></td>
</tr>
<tr>
<td height="74"><div align="right">圖片: </div></td>
<td><img src="upload/<%=item.getFileName() %>" width="85" height="49"> </td>
</tr>
<tr>
<td width="22%" height="29"><div align="right"><font color="#FF0000">*</font>選擇圖片: </div>
</td>
<td width="78%"><input name="fileName" type="file" class="text1" size="40" maxlength="40"></td>
</tr>
</table>
<div align="center">
<input name="btn_upload" class="button1" type="submit"
id="btn_upload" value="上傳">
<input name="btnBack" class="button1" type="button" id="btnBack"
value="返回" onClick="history.go(-1)">
</div>
</div>
</form>
為什麼上傳檔案的表單需要設定enctype=”multipart/form-data”
注意:使用enctype="multipart/form-data"
時,表單必須是post提交方式
當點選上傳按鈕時,表單就會將檔案內容也提交到HTML請求中了
三:servlet設定
package com.bjpowernode.drp.basedata.web;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.bjpowernode.drp.basedata.manager.ItemManager;
import com.bjpowernode.drp.basedata.manager.ItemManagerImpl;
import com.bjpowernode.drp.util.ApplicationException;
public class FileUploadServlet extends AbstractItemServlet {
//檔案下載存放路徑
private File uploadPath;
//臨時檔案存放路徑
private File tempPath;
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
//1.apache的核心API:DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
//1.1設定記憶體緩衝區大小
factory.setSizeThreshold(4096);
//1.2指定臨時檔案目錄
factory.setRepository(tempPath);
//2.apache的核心API:ServletFileUpload ,負責處理上傳的檔案資料
ServletFileUpload upload = new ServletFileUpload(factory);
//2.1設定檔案上傳總量(所有上傳檔案)的最大值
upload.setSizeMax(1000000 * 20);
//2.2設定編碼格式
upload.setHeaderEncoding("UTF-8");
try {
//2.3.解析request物件,獲取傳過來的資料
List fileItems = upload.parseRequest(req);
String itemNo = "";
for (Iterator iter = fileItems.iterator(); iter.hasNext();) {
//3.apache的核心API:FileItem
FileItem item = (FileItem) iter.next();
//3.1是普通的表單輸入域
if(item.isFormField()) {
//
if ("itemNo".equals(item.getFieldName())) {
//3.2用於將FileItem物件中儲存的資料流內容以一個字串返回,
itemNo = item.getString();
}
}
//3.1是type=file的輸入域
if (!item.isFormField()) {
//3.2獲取檔名,IE為絕對路徑,Firefox只有檔名
String fileName = item.getName();
//3.3獲得上傳檔案的大小
long size = item.getSize();
if ((fileName == null || fileName.equals("")) && size == 0) {
continue;
}
//擷取字串 ,獲得檔名
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
//3.4 將FileItem物件中儲存的主體內容儲存到指定的檔案中
item.write(new File(uploadPath, fileName));
//呼叫業務邏輯層
itemManager.uploadItemImage(itemNo, fileName);
}
//重定向
res.sendRedirect(req.getContextPath() + "/servlet/item/SearchItemServlet");
} catch (Exception e) {
e.printStackTrace();
throw new ApplicationException("上傳失敗!");
}
}
public void init() throws ServletException {
//檔案存放目錄
//獲取servlet容器物件,相當於tomacat容器,getRealPath("upload")獲取upload檔案在容器中的實際釋出執行位置
uploadPath = new File(getServletContext().getRealPath("upload"));
//如果目錄不存在
if (!uploadPath.exists()) {
//建立目錄
uploadPath.mkdir();
}
//臨時目錄
tempPath = new File(getServletContext().getRealPath("temp"));
if (!tempPath.exists()) {
tempPath.mkdir();
}
//顯示呼叫父類的init方法,因為該類繼承了父類,覆蓋了父類的init()方法
super.init();
}
}
apache的核心API:DiskFileItemFactory:是建立FileItem 物件的工廠
public void setSizeThreshold(int sizeThreshold)
:設定記憶體緩衝區的大小,預設值為10K。當上傳檔案大於緩衝區大小時,fileupload元件將使用臨時檔案快取上傳檔案。public void setRepository(Java.io.File repository)
:
指定臨時檔案目錄,預設值為System.getProperty(“java.io.tmpdir”).
apache的核心API:ServletFileUpload ,負責處理上傳的檔案資料
setSizeMax(long sizeMax)
:設定上傳檔案總量的最大值(所有上傳檔案),用於設定請求訊息實體內容(即所有上傳資料)的最大尺寸限制,以防止客戶端惡意上傳超大檔案來浪費伺服器端的儲存空間。其引數是以位元組為單位的long型數字setFileSizeMax(long fileSizeMax)
:設定上傳檔案的最大值(單個檔案),用於設定單個上傳檔案的最大尺寸限制,以防止客戶端惡意上傳超大檔案來浪費伺服器端的儲存空間。其引數是以位元組為單位的long型數字setHeaderEncoding(java.lang.String encoding)
:設定編碼格式。在檔案上傳請求的訊息體中,除了普通表單域的值是文字內容以外,檔案上傳欄位中的檔案路徑名也是文字,在記憶體中儲存的是它們的某種字符集編碼的位元組陣列,Apache檔案上傳元件在讀取這些內容時,必須知道它們所採用的字符集編碼,才能將它們轉換成正確的字元文字返回。List parseRequest(HttpServletRequest request)
:解析request物件,並把表單中的每一個輸入項包裝成一個fileItem 物件,並返回一個儲存了所有FileItem的list集合(form提交採用multipart/form-data,無法採用req.getParameter()取得資料)- boolean isMultipartContent(HttpServletRequest request) :判斷上傳表單是否為multipart/form-data型別
3. apache的核心API:FileItem:是個介面,用來阻止所有的檔案,通過這個統一介面訪問檔案的資訊
boolean isFormField()
: isFormField方法用於判斷FileItem類物件封裝的資料是一個普通文字表單欄位,還是一個檔案表單欄位,如果是普通表單欄位則返回true,否則返回false。String getString()
:用於將FileItem物件中儲存的資料流內容以一個字串返回,它有兩個過載的定義形式:
public Java.lang.String getString();使用預設的字符集編碼將主體內容轉換成字串
public java.lang.String getString(java.lang.String encoding) throws java.io.UnsupportedEncodingException
使用引數指定的字符集編碼將主體內容轉換成字串。如果在讀取普通表單欄位元素的內容時出現了中文亂碼現象,請呼叫第二個getString方法,併為之傳遞正確的字符集編碼名稱void write(File file)
:用於將FileItem物件中儲存的主體內容儲存到某個指定的檔案中。如果FileItem物件中的主體內容是儲存在某個臨時檔案中,該方法順利完成後,臨時檔案有可能會被清除。該方法也可將普通表單欄位內容寫入到一個檔案中,但它主要用途是將上傳的檔案內容儲存在本地檔案系統中。在此,臨時檔案儲存在專案釋出的tomacat的根目錄下的temp資料夾,但是檔案最終儲存的目錄是upload資料夾long getSize()
:返回上傳檔案的大小String getName()
:用於獲得檔案上傳欄位中的檔名。注意IE或FireFox中獲取的檔名是不一樣的,IE中是絕對路徑,FireFox中只是檔名
問題:
上傳的圖片名字有中文時亂碼,圖片也載入不出來,除錯檢查元素時,手動把.jsp頁面的<img src="">
圖片路徑改為中文的也載入不出來,改為不是中文的就能載入出來,把upload.setHeaderEncoding("UTF-8");
改為upload.setHeaderEncoding("GBK");
就能載入出來了;嘗試使用public java.lang.String getString(java.lang.String encoding)
的建構函式,在此使用改變編碼格式,但是不起作用
總結
相關文章
- 圖片上傳5-多個圖片上傳,獨立專案Demo和原始碼原始碼
- ServletFileUpload類上傳檔案Servlet
- 上傳圖片和檔案出錯!!!
- 圖片檔案上傳
- flask部落格專案之tinymce圖片上傳Flask
- JAVA web ServletFileUpload檔案上傳遇到大量50+錯誤的解決方法JavaWebServlet
- web前端圖片上傳(3)–filereaderWeb前端
- 利用vue-cropper剪裁圖片並上傳Vue
- jsp+springmvc實現檔案上傳、圖片上傳和及時預覽圖片JSSpringMVC
- Ueditor 上傳圖片自動新增水印(只能上傳圖片,上傳檔案報錯)
- 上傳圖片
- 我需要在Web上完成一個圖片上傳的功能Web
- 探索Django:從專案建立到圖片上傳的全方位指南Django
- [開源專案] Laravel 圖片上傳元件,支援直傳雲端儲存Laravel元件
- 專案分享五:H5圖片壓縮與上傳H5
- 上傳專案到gitHub,上傳報錯和刪除gitHub上的專案Github
- PHP實現圖片(檔案)上傳PHP
- php圖片上傳之檔案安全PHP
- 我需要在Web上完成一個圖片上傳的功能(+2)Web
- Vue專案中最簡單的使用整合UEditor方式,含圖片上傳Vue
- 利用藍芽來傳送圖片等檔案藍芽
- Retrofit+RxJava上傳圖片上傳圖片到後臺RxJava
- Ueditor上傳圖片自動新增水印(通用圖片檔案)
- 【easyui 】上傳圖片UI
- 上傳圖片jsJS
- WebClient和HttpClient, 以及webapi上傳圖片WebclientHTTPAPI
- PbootCMS上傳圖片變模糊、上傳圖片尺寸受限的解決方案boot
- 圖片上傳及圖片處理
- web技術分享| 圖片上傳與圖片裁剪結合 vue3WebVue
- curl上傳圖片的大坑
- 如何實現一個簡易的圖片上傳Web ServerWebServer
- 基於Web3.0的區塊鏈圖片上傳Web區塊鏈
- 上傳封面圖片前臺不顯示 Picture檔案裡可以看到上傳的圖片
- php圖片上傳之圖片轉換PHP
- 利用微信公眾號提供的官方API上傳圖片獲取永久圖片素材!當圖床用!API圖床
- [筆記]laravel的上傳檔案或者圖片的方法筆記Laravel
- java,springboot + thymeleaf 上傳圖片、刪除圖片到伺服器、本地,壓縮圖片上傳(有些圖片會失真),原圖上傳JavaSpring Boot伺服器
- 如何在 Laravel 專案中輕鬆實現拖拽和剪下板黏貼上傳圖片?Laravel