在Web應用中,由於大多數文件的上傳都是通過表單的形式提交給伺服器的,因此,要想在程序中實現文件上傳的功能,首先得創建一個用於提交上傳文件的表單頁面。
標籤的使用需要注意以下兩點:
必須要設置input輸入項的name屬性,否則瀏覽器將不會發送上傳文件的數據。
必須把將表單頁面的method屬性設置為post方式,文件的上傳是通過二進位的形式上傳數據的,enctype屬性設置為「multipart/form-data」類型
<form enctype=「multipart/form-data」 method=「post」>
選擇上傳文件:<input type=「file」 name=「myfile」/><br />
</form>
開發工具:Intellij IDEA/Eclipse
所需jar包:commons-fileupload-1.*.jar和commons-io-1.4.jar
jar包下載網址:https://mvnrepository.com/
也可以通過微信公眾號源碼客棧回復 」jar"領取jar包的網盤地址下載
我們用到的有isFormFied()、getName()、getFiedName()、write(File file) 、getString()、void delete()等
DiskFileItemFactory工廠類說明DiskFileItemFactory類用於將請求消息實體中的每一個文件封裝成單獨的FileItem對象。如果上傳的文件比較小,將直接保存在內存中,如果上傳的文件比較大,則會以臨時文件的形式,保存在磁碟的臨時文件夾中。默認情況下,文件保存在內存還是硬碟臨時文件夾的臨界值是10240,即10kb。
DiskFileItemFactory類的兩個構造方法:
DiskFileItemFactory():採用默認臨界值和系統臨時文件夾構造文件項工廠對象
DiskFileItemFactory(int sizeThreshold,File repository):採用參數指定臨界值和系統臨時文件夾構造文件項工廠對象
ServletFileUpload():構造一個未初始化的ServletFileUpload實例對象
ServletFileUpload(FileItemFactory fileItemFactory):根據參數指定的FileItemFactory 對象創建一個ServletFileUpload對象
ServletFileUpload類是Apache組件處理文件上傳的核心高級類,通過使用parseRequest(HttpServletRequest) 方法可以將HTML中每個表單提交的數據封裝成一個FileItem對象,然後以List列表的形式返回。
對於文件下載,人們並不陌生,我們經常會在某網站下載圖片,下載電影等等。
實現文件下載功能比較簡單,直接使用Servlet類和輸入/輸出流即可實現。實現文件的下載,不僅需要指定文件的路徑,還需要在HTTP協議中設置兩個響應消息頭:
//設定接受程序處理數據的方式
Content-Disposition:attachment; filename =
//設定試題內容的MIME類型
Content-Type:application/x-msdownload
瀏覽器通常會直接處理響應的實體內容。當我們需要在HTTP響應消息中設置這兩個響應消息頭欄位,來指定接收程序處理數據內容的方式為下載方式,當單擊「下載」超連結時,系統將請求提交到對應的Servlet。在該Servlet中,首先獲取下載文件的地址,並根據該地址創建文件字節輸入流,然後通過該流讀取下載文件內容,最後將讀取的內容通過輸出流寫到目標文件中。
項目骨架創建實體類我們通過實體類來暫時保存表單裡面的value值和文件的路徑
private String username;
private String photo;
//setter和getter方法
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", photo='" + photo + '\'' +
'}';
}
web.xml配置<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<servlet>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>edu.ymkz.web.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>edu.ymkz.web.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/DownloadServlet</url-pattern>
</servlet-mapping>
</web-app>
上傳文件 fileupload.jsp<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form enctype="multipart/form-data" action="/UploadServlet" method="post">
用戶名:<input type="text" name="username"><br>
頭像:<input type="file" name="photo"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
UploadServlet(處理下載請求)package edu.ymkz.web;
import edu.ymkz.entity.User;
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 javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class UploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);//調用doPost方法
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");//處理亂碼
String path="D:\\Program Files\\JetBrains\\idea_projects\\java web\\file_upload\\web\\file\\";
//默認的文件保存路徑,也就是項目的工程所在位置
//先判斷是否是多段的數據,如果返回true,表示普通的表單項,false為文件
if(ServletFileUpload.isMultipartContent(req)){
FileItemFactory fileItemFactory=new DiskFileItemFactory();//創建本地文件系統
ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);
try {
List<FileItem> list=servletFileUpload.parseRequest(req);//解析多段數據
User user=new User();
for(FileItem fileItem:list){
if(fileItem.isFormField()){//普通表單項
user.setUsername(fileItem.getString("utf-8"));//保存普通表但的值
System.out.println("表單項的name值"+fileItem.getFieldName());
System.out.println("表單項的value值"+fileItem.getString("utf-8"));//解決亂碼
}else{//文件
user.setPhoto(path+fileItem.getName());//把圖片的路徑保存起來
System.out.println("表單項的name值"+fileItem.getFieldName());
System.out.println("表單項的value值"+fileItem.getName());//解決亂碼
fileItem.write(new File(path+fileItem.getName()));
}
}
System.out.println(user.toString());//列印出保存的value值
}catch (Exception e){
e.printStackTrace();
}
}
}
}
UploadServlet列印結果文件下載 download.jsp若圖片上傳之後不顯示,請刪除項目裡的out目錄然後重新部署,就可以了.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<img src="/file/ymkz.jpg" /><br>
<a href="/DownloadServlet?filename=源碼客棧.jpg">下載</a>
</body>
</html>
文件下載DownloadServet超連結時doGet方法,當請求傳到doGet方法之後再調用doPost方法
package edu.ymkz.web;
import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.descriptor.JspConfigDescriptor;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Map;
import java.util.Set;
@WebServlet(name = "DownloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String downloadFileName = request.getParameter("filename");
System.out.println(downloadFileName);
ServletContext servletContext = getServletContext();
String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
System.out.println("下載的文件類型" + mimeType);
response.setContentType(mimeType);
//attachment表示附件,filename是文件名,表示用來下載的文件名
if (request.getHeader("User-Agent").contains("Firefox")) {
response.setHeader("Content-Disposition", "attachment;filename=?UTF-8?B?" + new BASE64Encoder().encode(downloadFileName.getBytes("UTF-8")) + "?=");
} else {//處理下載之後文件名 為亂碼,針對ie google等瀏覽器
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadFileName, "utf-8"));
}
//火狐,谷歌兼容性最好
InputStream inputStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
byte[] bytes = new byte[1024];
OutputStream outputStream = response.getOutputStream();
IOUtils.copy(inputStream, outputStream);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
本程序源碼案例下載網盤地址
連結:https://pan.baidu.com/s/1skoWj9c9bm0Ue-aCZGS35w
提取碼:7f6f
若網盤連接失效,公眾號窗口留言即可