Java中使用fileupload組件實(shí)現(xiàn)文件上傳功能的實(shí)例代碼
使用fileupload組件的原因:
Request對(duì)象提供了一個(gè)getInputStream()方法,通過這個(gè)方法可以讀取到客戶端提交過來的數(shù)據(jù),但是由于用戶可能會(huì)同時(shí)上傳多個(gè)文件,在servlet中編程解析這些上傳數(shù)據(jù)是一件非常麻煩的工作。為方便開發(fā)人員處理文件上傳數(shù)據(jù),Apache開源組織提供了一個(gè)用來處理表單文件上傳的一個(gè)開源組件(Commons-fileupload),該組件性能優(yōu)異,并且使用及其簡(jiǎn)單,可以讓開發(fā)人員輕松實(shí)現(xiàn)web文件上傳功能。
使用Commons-fileupload組件實(shí)現(xiàn)文件上傳,需要導(dǎo)入該組件相應(yīng)的支撐jar包:
commons-fileupload和connons-io(commons-upload組件從1.1版本開始,它的工作需要commons-io包的支持)
FileUpload組件工作流程:

相應(yīng)的代碼框架為:
package pers.msidolphin.uploadservlet.web;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.UUID;
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;
/**
* Servlet implementation class UploadServlet
*/
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public UploadServlet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取解析工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
//得到解析器
ServletFileUpload parser = new ServletFileUpload(factory);
//解決文件名亂碼問題
parser.setHeaderEncoding("UTF-8");
//判斷上傳表單類型
if(!ServletFileUpload.isMultipartContent(request)) {
return;
}
try {
//調(diào)用解析器解析上傳數(shù)據(jù)
List<FileItem> fileItems = parser.parseRequest(request);
//獲得保存上傳文件目錄的路徑
String uploadPath = request.getServletContext().getRealPath("/WEB-INF/upload");
//遍歷List集合
for (FileItem fileItem : fileItems) {
//判斷是否為普通表單字段
if(fileItem.isFormField()) {
//如果是普通表單字段則打印到控制臺(tái)
if(fileItem.getString() == null || "".equals(fileItem.getString().trim())) {
continue;
}
System.out.println(fileItem.getFieldName() + " = " + new String(fileItem.getString().getBytes("ISO-8859-1"), "UTF-8"));
}else {
//獲得文件路徑
String filePath = fileItem.getName();
//如果并未上傳文件,繼續(xù)處理下一個(gè)字段
if(filePath == null || "".equals(filePath.trim())) {
continue;
}
System.out.println("處理文件:" + filePath);
//截取文件名
String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);
String reallyName = this.createFileName(fileName);
String reallyPath = this.mkDir(reallyName, uploadPath);
//下面都是普通的IO操作了
InputStream in = fileItem.getInputStream();
FileOutputStream out = new FileOutputStream(reallyPath + "\\" + reallyName);
byte[] buffer = new byte[1024];
int len = 0;
while((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.close();
in.close();
}
}
System.out.println("處理完畢...");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
//隨機(jī)產(chǎn)生唯一的文件名
private String createFileName(String fileName) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String extension = fileName.substring(fileName.lastIndexOf("."));
MessageDigest md = MessageDigest.getInstance("md5");
String currentTime = System.currentTimeMillis() + "";
return UUID.randomUUID() + currentTime + extension;
}
//根據(jù)哈希值產(chǎn)生目錄
private String mkDir(String fileName, String uploadPath) {
int hasCode = fileName.hashCode();
//低四位作為一級(jí)目錄
int parentDir = hasCode & 0xf;
//二級(jí)目錄
int childDir = hasCode & 0xff >> 2;
File file = new File(uploadPath + "\\" + parentDir + "\\" + childDir);
if(!file.exists()) {
file.mkdirs();
}
uploadPath = uploadPath + "\\" + parentDir + "\\" + childDir;
return uploadPath;
}
}
JSP頁(yè)面 :
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!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>
<fmt:setBundle basename="pers.msidolphin.uploadservlet.lang.locale" var="bundle" scope="page"/>
<form action="<c:url value="/UploadServlet"/>" method="post" enctype="multipart/form-data">
<fmt:message key="username" bundle="${bundle}"/><input type="text" name="username"/>
<br/>
<br/>
<fmt:message key="file1" bundle="${bundle}"/><input type="file" name="file1"/>
<br/>
<br/>
<fmt:message key="file2" bundle="${bundle}"/><input type="file" name="file2"/>
<br/>
<br/>
<input type="submit" value="<fmt:message key="submit" bundle="${bundle}"/>"/>
</form>
</body>
</html>
核心API: DiskFileItemFactory類
//設(shè)置內(nèi)存緩沖區(qū)的大小,默認(rèn)為10K,當(dāng)上傳文件大小大于緩沖區(qū)大小,fileupload組件將使用臨時(shí)文件緩存上傳文件
public void setSizeThreshold(int sizeThreshold);
//指定臨時(shí)文件目錄 默認(rèn)值為System.getProperty("java.io.tmpdir")
public void setRepository(java.io.file respository);
//構(gòu)造方法
public DiskFileItemFactory(int sizeThreshold, java.io.file respository);
核心API: ServletFileUpload類
//判斷上傳表單是否為multipart/form-data類型 boolean isMultipartContent(HttpServletRequest request); //解析request對(duì)象,并把表單中的每一個(gè)輸入項(xiàng)包裝成一個(gè)fileitem對(duì)象,返回這些對(duì)象的list集合 List<FileItem> parseRequest(HttpServletRequest request); //設(shè)置上傳文件總量的最大值 單位:字節(jié) void setSizeMax(long sizeMax); //設(shè)置單個(gè)上傳文件的最大值 單位:字節(jié) void setFileSizeMax(long fileSizeMax); //設(shè)置編碼格式,用于解決上傳文件名的亂碼問題 void setHeaderEncoding(String encoding); //設(shè)置文件上傳監(jiān)聽器,作用是實(shí)時(shí)獲取已上傳文件的大小 void setProgressListener(ProgressListener pListener);
核心API: FileItem類
//判斷表單輸入項(xiàng)是否為普通輸入項(xiàng)(非文件輸入項(xiàng),如果是普通輸入項(xiàng)返回true boolean isFormField(); //獲取輸入項(xiàng)名稱 String getFieldName(); //獲得輸入項(xiàng)的值 String getString(); String getString(String encoding); //可以設(shè)置編碼,用于解決數(shù)據(jù)亂碼問題 以下是針對(duì)非普通字段的: //獲取完整文件名(不同的瀏覽器可能會(huì)有所不同,有的可能包含路徑,有的可能只有文件名) String getName(); //獲取文件輸入流 InputStream getInputStream();
文件上傳的幾個(gè)注意點(diǎn):
1、上傳文件的文件名亂碼問題:ServletFileUpload對(duì)象提供了setHeaderEncoding(String encoding)方法可以解決中文亂碼問題
2、上傳數(shù)據(jù)的中文亂碼問題:
解決方法一:new String(fileItem.getString().getBytes(“ISO-8859-1”), “UTF-8”)
解決方法二:fileItem.getString(“UTF-8”)
解決方法三:fileItem.getString(request.getCharacterEncoding())
3、上傳文件名的唯一性:UUID、MD5解決方法很多…
4、保存上傳文件的目錄最好不要對(duì)外公開
5、限制上傳文件的大小: ServletFileUpload對(duì)象提供了setFileSizeMax(long fileSizeMax)和setSizeMax(long sizeMax)方法用于解決這個(gè)問題
6、限制文件上傳類型:截取后綴名進(jìn)行判斷(好像不太嚴(yán)格,還要研究一番…)
以上所述是小編給大家介紹的Java中使用fileupload組件實(shí)現(xiàn)文件上傳功能的實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- java組件SmartUpload和FileUpload實(shí)現(xiàn)文件上傳功能
- java使用common-fileupload實(shí)現(xiàn)文件上傳
- java組件commons-fileupload實(shí)現(xiàn)文件上傳、下載、在線打開
- Java組件commons fileupload實(shí)現(xiàn)文件上傳功能
- JavaEE組件commons-fileupload實(shí)現(xiàn)文件上傳、下載
- java組件commons-fileupload文件上傳示例
- java組件fileupload文件上傳demo
- java組件commons-fileupload實(shí)現(xiàn)文件上傳
- JAVA使用commos-fileupload實(shí)現(xiàn)文件上傳與下載實(shí)例解析
- 使用fileupload組件實(shí)現(xiàn)文件上傳功能
相關(guān)文章
Java使用注解實(shí)現(xiàn)防止重復(fù)提交實(shí)例
這篇文章主要介紹了Java使用注解實(shí)現(xiàn)防止重復(fù)提交實(shí)例,在一些項(xiàng)目中由于用戶誤操作,多次點(diǎn)擊表單提交按鈕,會(huì)產(chǎn)生很多次的數(shù)據(jù)交互,為了解決這一問題,本文使用注解來實(shí)現(xiàn)防止重復(fù)提交,需要的朋友可以參考下2023-07-07
mybatisplus實(shí)現(xiàn)自動(dòng)創(chuàng)建/更新時(shí)間的項(xiàng)目實(shí)踐
Mybatis-Plus提供了自動(dòng)填充功能,可以通過實(shí)現(xiàn)MetaObjectHandler接口來實(shí)現(xiàn)自動(dòng)更新時(shí)間的功能,本文就來介紹一下mybatisplus實(shí)現(xiàn)自動(dòng)創(chuàng)建/更新時(shí)間的項(xiàng)目實(shí)踐,感興趣的可以了解下2024-01-01
Java并發(fā)編程之閉鎖與柵欄的實(shí)現(xiàn)
這篇文章主要介紹了Java并發(fā)編程之閉鎖與柵欄的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Java字節(jié)緩存流的構(gòu)造方法之文件IO流
這篇文章主要介紹了Java字節(jié)緩存流的構(gòu)造方法之文件IO流,同時(shí)也介紹了字符流中的一些相關(guān)的內(nèi)容,并且通過大量的案例供大家理解。最后通過一些經(jīng)典的案例幫助大家對(duì)前面所學(xué)的知識(shí)做了一個(gè)綜合的應(yīng)用,需要的朋友可以參考一下2022-04-04
java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹
這篇文章主要介紹了java 中多線程生產(chǎn)者消費(fèi)者問題詳細(xì)介紹的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09
java使用EditText控件時(shí)不自動(dòng)彈出輸入法的方法
這篇文章主要介紹了java使用EditText控件時(shí)不自動(dòng)彈出輸入法的方法,需要的朋友可以參考下2015-03-03
SpringBoot中引入MyBatisPlus的常規(guī)操作
這篇文章主要介紹了SpringBoot中引入MyBatisPlus的常規(guī)操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

