1. 程式人生 > >java實現檔案上傳下載的三種方法

java實現檔案上傳下載的三種方法

JSP+Servlet

一、檔案上傳下載原理

在TCP/IP中,最早出現的檔案上傳機制是FTP。它是將檔案由客戶端傳送到伺服器的標準機制。但是在jsp程式設計中不能使用FTP方法來上傳檔案,這是由jsp的執行機制所決定的。

通過為表單元素設定Method=“post” enctype="multipart/form-data"屬性,讓表單提交的資料以二進位制編碼的方式提交,在接收此請求的Servlet中用二進位制流來獲取內容,就可以取得上傳檔案的內容,從而實現檔案的上傳。

二、enctype屬性的選擇值範圍

1、application/x-www-form-urlencoded:這是預設編碼方式,它只處理表單域裡的value屬性值,採用這種編碼方式的表單會將表單域的值處理成url編碼方式。

2、multipart/form-data:這種編碼方式的表單會以二進位制流的方式來處理表單資料,這種編碼方式會把檔案域指定的檔案內容也封裝到請求引數裡。

3、text/plain:這種方式主要適用於直接通過表單傳送郵件的方式。

程式碼內容

1.將檔案讀取到伺服器指定目錄下

2.獲取檔案內容的起止位置,和檔名稱

3.將檔案儲存到專案的指定目錄下

<span style="font-size:18px;">public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//從request中獲取輸入流資訊
		InputStream fileSource = request.getInputStream();
		//建立儲存在伺服器的路徑資訊
		String tempFileName = "H:/tempFile";
		//指向臨時檔案
		File tempFile = new File(tempFileName);
		//outPutStream輸出流指向臨時檔案
		FileOutputStream outputStream = new FileOutputStream(tempFile); 
		//每次讀取檔案位元組
		byte b[] = new byte[1024];
		int n;
		while((n=fileSource.read(b))!=-1){
			outputStream.write(b,0,n);
		}
		
		//關閉輸出輸入流
		fileSource.close();
		outputStream.close();
		
		//獲取上傳檔案的名稱
		RandomAccessFile randomFile = new RandomAccessFile(tempFile, "r");
		randomFile.readLine();  //獲取第一行資料(對我們來說沒有意義)
		String str = randomFile.readLine();  //獲取第二行資料,內容為:Content-Disposition: form-data; name="myfile"; filename="C:\Users\lihf\Desktop\hello.txt"
		int beginIndex = str.lastIndexOf("\\")+1;
		int endIndex = str.lastIndexOf("\"");
		String fileName = str.substring(beginIndex, endIndex);
		
		//重新定位檔案指標到標頭檔案
		randomFile.seek(0);
		long startPosition=0;
		int i=1;
		//獲取檔案內容開始位置
		while((n=randomFile.readByte())!=-1&&i<=4){
			if(n=='\n'){
				startPosition = randomFile.getFilePointer();
				i++;
			}
		}
		startPosition = randomFile.getFilePointer() -1;
		//獲取檔案結束位置
		randomFile.seek(randomFile.length());  //檔案指標定位到檔案末尾
		long endPosition = randomFile.getFilePointer();
		int j=1;
		while(endPosition>=0&&j<=2){
			endPosition--;
			randomFile.seek(endPosition);
			if(randomFile.readByte()=='\n'){
				j++;
			}
		}
		endPosition = endPosition -1;
		
		//設定儲存檔案上傳的路徑
		String realPath = getServletContext().getRealPath("/")+"images";
		System.out.println("儲存檔案上傳的路徑:"+realPath);
		File fileupload = new File(realPath);
		if(!fileupload.exists()){
			fileupload.mkdir();  //建立此抽象路徑名指定的目錄。 
		}
		File saveFile = new File(realPath, fileName);
		RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,"rw");
		//從臨時檔案中讀取檔案內容(根據檔案起止位置獲取)
		randomFile.seek(startPosition);
		while(startPosition<endPosition){
			randomAccessFile.write(randomFile.readByte());
			startPosition = randomFile.getFilePointer();
		}
		
		//關閉輸入輸出流
		randomAccessFile.close();
		randomFile.close();
		tempFile.delete();
		 	
		request.setAttribute("result", "上傳成功!");
		RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");
		dispatcher.forward(request, response);
	}</span>

三、檔案下載原理

1、step1:需要通過HttpServletResponse.setContentType方法設定Content-type頭欄位的值,為瀏覽器無法使用某種方式或啟用某個程式來處理的MIME型別,例如,“application/octet-stream”或“application/x-msdownload”等。

2、step2:需要通過HttpServletResponse.setHeader方法設定Content-Disposition頭的值為“attachment;filename=檔名”。

3、step3:讀取下載檔案,呼叫HttpServletResponse.getOutputStream方法返回的OutputStream物件來向客戶端寫入附件檔案內容。

<span style="font-size:18px;">public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//獲取檔案下載路徑
		String path = getServletContext().getRealPath("/") + "images/";
		String filename = request.getParameter("filename");
		File file = new File(path + filename);
		if(file.exists()){
			//設定相應型別application/octet-stream
			response.setContentType("application/x-msdownload");
			//設定頭資訊
			response.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
			InputStream inputStream = new FileInputStream(file);
			ServletOutputStream ouputStream = response.getOutputStream();
			byte b[] = new byte[1024];
			int n ;
			while((n = inputStream.read(b)) != -1){
				ouputStream.write(b,0,n);
			}
			//關閉流、釋放資源
			ouputStream.close();
			inputStream.close();
		}else{
			request.setAttribute("errorResult", "檔案不存在下載失敗!");
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");
			dispatcher.forward(request, response);
		}
	}</span>
JSP頁面內容:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP '01.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link rel="stylesheet" type="text/css" href="css/common.css" />
	<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
	<script type="text/javascript">
		$(function(){
			$(".thumbs a").click(function(){
				var largePath=$(this).attr("href");
				var largeAlt=$(this).attr("title");
				$("#largeImg").attr({
					src:largePath,
					alt:largeAlt
				});
				return false;
			});
			$("#myfile").change(function(){
				$("previewImg").attr("src","file:///"+$("#myfile").val());
			});
			
			var la = $("#large");
			la.hide();
			
			$("#previewImg").mousemove(function(e){
				la.css({
					top:e.pagey,
					left:e.pagex
				}).html('<img src="'+this.src+'" />');
			}).mouseout(function(){
				la.hide();
			});
			
		});
		/* function showPreview(obj){
			var str = obj.value;
			document.getElementById("previewImg").innerHTML=
				"<img src='"+str+"'/>";
				alert(document.getElementById("previewImg").innerHTML);
		} */
	</script>
  </head>
  
  <body>
  	<img id="previewImg" src="images/preview.jpg" width="80" height="80" />
  <form action="uploadServlet.do" method="post" enctype="multipart/form-data">
  	請選擇上傳圖片:<input type="file" id="myfile" name="myfile" onchange="showPreview(this)" />
  	<input type="submit" value="提交"/>
  </form>
  下載<a href="downloadServlet.do?filename=hello.txt">hello.txt</a>   ${errorResult}
  <div id="large"></div>
  <!-- <form action="">
  	請選擇上傳圖片:<input type="file" id="myfile" name="myfile" onchange="showPreview(this)" />
  	<div id="previewImg"></div>
  </form> -->
   <hr>
   <h2>圖片預覽</h2>
    <p><img id="largeImg" src="images/img1-lg.jpg" alt="Large Image"/></p>
    <p class="thumbs">
    	<a href="images/img2-lg.jpg" title="Image2"><img src="images/img2-thumb.jpg"></a>
    	<a href="images/img3-lg.jpg" title="Image3"><img src="images/img3-thumb.jpg"></a>
    	<a href="images/img4-lg.jpg" title="Image4"><img src="images/img4-thumb.jpg"></a>
    	<a href="images/img5-lg.jpg" title="Image5"><img src="images/img5-thumb.jpg"></a>
    	<a href="images/img6-lg.jpg" title="Image6"><img src="images/img6-thumb.jpg"></a>
    </p>
  </body>
</html>
SmartUpload實現上傳下載

使用非常簡單,直接引入SmartUpload的jar檔案就可以啦

<span style="font-size:18px;">public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//設定上傳檔案儲存路徑
		String filePath = getServletContext().getRealPath("/")+"images";
		File file = new File(filePath);
		if(!file.exists()){
			file.mkdir();
		}
		SmartUpload su = new SmartUpload();
		//初始化smartUpload
		su.initialize(getServletConfig(), request, response);
		//設定上傳檔案大小
		su.setMaxFileSize(1024*1024*10);
		//設定所有檔案的大小
		su.setTotalMaxFileSize(102481024*100);
		//設定允許上傳檔案的型別
		su.setAllowedFilesList("txt,jpg,gif");
		String result = "上傳能成功";
		try {
			//設定禁止上傳檔案型別
			su.setDeniedFilesList("jsp,rar");
			su.upload();
			int count = su.save(filePath);
			System.out.println("上傳成功"+count+"檔案!");
		} catch (Exception e) {
			result="上傳檔案失敗!";
<span style="white-space:pre">			</span>if(e.getMessage().indexOf("1015")!=-1){<span style="white-space:pre">				</span>
<span style="white-space:pre">				</span>result = "上傳檔案失敗:上傳檔案型別不正確!";
<span style="white-space:pre">			</span>}else if(e.getMessage().indexOf("1010")!=-1){
<span style="white-space:pre">				</span>result = "上傳檔案失敗:上傳檔案型別不正確!";
<span style="white-space:pre">			</span>}else if(e.getMessage().indexOf("1105")!=-1){
<span style="white-space:pre">				</span>result = "上傳檔案失敗:上傳檔案大小大於允許上傳的最大值!";
<span style="white-space:pre">			</span>}else if(e.getMessage().indexOf("1110")!=-1){
<span style="white-space:pre">				</span>result = "上傳檔案失敗:上傳檔案的總大小大於我們允許上傳總大小的最大值!";
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>e.printStackTrace();
		}
		for(int i=0;i<su.getFiles().getCount();i++){
<span style="white-space:pre">			</span>com.jspsmart.upload.File tempFile = su.getFiles().getFile(i);
<span style="white-space:pre">			</span>System.out.println("表單當中name屬性值:"+tempFile.getFieldName());
<span style="white-space:pre">			</span>System.out.println("上傳檔名:"+tempFile.getFileName());
<span style="white-space:pre">			</span>System.out.println("上傳檔案的大小:"+tempFile.getSize());
<span style="white-space:pre">			</span>System.out.println("上傳檔名拓展名:"+tempFile.getFileExt());
<span style="white-space:pre">			</span>System.out.println("上傳檔案的全名:"+tempFile.getFilePathName());
<span style="white-space:pre">		</span>}
		request.setAttribute("result",result);
		request.getRequestDispatcher("jsp/02.jsp").forward(request, response);
	}</span>
jsp頁面表單提交內容:
<span style="font-size:18px;"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP '02.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link rel="stylesheet" type="text/css" href="css/common.css" />
	<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
	<script type="text/javascript">
		$(function(){
			$(".thumbs a").click(function(){
				var largePath=$(this).attr("href");
				var largeAlt=$(this).attr("title");
				$("#largeImg").attr({
					src:largePath,
					alt:largeAlt
				});
				return false;
			});
		});
	</script>
  </head>
  <body>
  	<form action="smartUploadServlet.do" method="post" enctype="multipart/form-data">
  		上傳檔案1:<input type="file" name="myfile1"/><br>
  		上傳檔案2:<input type="file" name="myfile2"/><br>
  		上傳檔案3:<input type="file" name="myfile3"/><br>
  		<input type="submit" value="提交"> ${result}
  	</form>
   <hr></span>
<span style="font-size:18px;">  下載:<a href="smartDownloadServlet.do?filename=img5-lg.jpg">img5-lg.jpg</a>
   <hr>
   <h2>圖片預覽</h2>
    <p><img id="largeImg" src="images/img1-lg.jpg" alt="Large Image"/></p>
    <p class="thumbs">
    	<a href="images/img2-lg.jpg" title="Image2"><img src="images/img2-thumb.jpg"></a>
    	<a href="images/img3-lg.jpg" title="Image3"><img src="images/img3-thumb.jpg"></a>
    	<a href="images/img4-lg.jpg" title="Image4"><img src="images/img4-thumb.jpg"></a>
    	<a href="images/img5-lg.jpg" title="Image5"><img src="images/img5-thumb.jpg"></a>
    	<a href="images/img6-lg.jpg" title="Image6"><img src="images/img6-thumb.jpg"></a>
    </p>
  </body>
</html></span>
<span style="font-size:18px;"><span style="background-color: rgb(255, 255, 255);">下載部分的程式碼</span></span>
<span style="font-size:18px;">public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String filename = request.getParameter("filename");
		SmartUpload su = new SmartUpload();
		su.initialize(getServletConfig(), request, response);
		su.setContentDisposition(null);
		try {
			su.downloadFile("/images/"+filename);
		} catch (SmartUploadException e) {
			e.printStackTrace();
		}
	}</span>

Struts2實現上傳下載:

上傳jsp頁面程式碼:

<span style="font-size:18px;"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP '03.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link rel="stylesheet" type="text/css" href="css/common.css" />
	<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
	<script type="text/javascript">
		$(function(){
			$(".thumbs a").click(function(){
				var largePath=$(this).attr("href");
				var largeAlt=$(this).attr("title");
				$("#largeImg").attr({
					src:largePath,
					alt:largeAlt
				});
				return false;
			});
		});
	</script>
  </head>
  <body>
  	<h2> 檔案上傳</h2>
  	<form action="upload.action" method="post" enctype="multipart/form-data">
  		上傳檔案1:<input type="file" name="upload"/><br>
  		上傳檔案2:<input type="file" name="upload"/><br>
  		上傳檔案3:<input type="file" name="upload"/><br>
  		<input type="submit" value="提交"> ${result}
  	</form>
   <hr>
   <h2>圖片預覽</h2>
    <p><img id="largeImg" src="images/img1-lg.jpg" alt="Large Image"/></p>
    <p class="thumbs">
    	<a href="images/img2-lg.jpg" title="Image2"><img src="images/img2-thumb.jpg"></a>
    	<a href="images/img3-lg.jpg" title="Image3"><img src="images/img3-thumb.jpg"></a>
    	<a href="images/img4-lg.jpg" title="Image4"><img src="images/img4-thumb.jpg"></a>
    	<a href="images/img5-lg.jpg" title="Image5"><img src="images/img5-thumb.jpg"></a>
    	<a href="images/img6-lg.jpg" title="Image6"><img src="images/img6-thumb.jpg"></a>
    </p>
  </body>
</html></span>
struts.xml部分程式碼
<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <!-- 國際化 -->
	<constant name="struts.custom.i18n.resources" value="app"></constant>
    <package name="default" namespace="/" extends="struts-default">
			<action name="upload" class="com.lihf.action.FileUploadAction">
					<result>/jsp/03.jsp</result>
					<result name="input">/jsp/error.jsp</result>
					<!-- 配置攔截器限制上傳檔案型別及大小 -->
					<interceptor-ref name="fileUpload">
						<param name="allowedTypes">image/bmp,image/x-png,image/gif,image/pjpeg</param>
						<param name="maximumSize">2M</param>
					</interceptor-ref>
					<interceptor-ref name="defaultStack"></interceptor-ref>
			</action>
			<action name="download" class="com.lihf.action.DownLoadAction">
				<param name="inputPath">/images/img2-lg.jpg</param>
				<result name="success" type="stream">
					<param name="contentType">application/octet-stream</param>
					<param name="inputName">inputStream</param>
					<!-- 以附件的形式下載 -->
					<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
					<param name="bufferSize">8192</param>
				</result>
			</action>
    </package>
</struts></span>
web.xml部分程式碼
<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>scxz</display-name>
  <servlet>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>com.lihf.servlet.UploadServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>DownloadServlet</servlet-name>
    <servlet-class>com.lihf.servlet.DownloadServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>SmartUploadServlet</servlet-name>
    <servlet-class>com.lihf.servlet.SmartUploadServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>SmartDownloadServlet</servlet-name>
    <servlet-class>com.lihf.servlet.SmartDownloadServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/uploadServlet.do</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>DownloadServlet</servlet-name>
    <url-pattern>/downloadServlet.do</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>SmartUploadServlet</servlet-name>
    <url-pattern>/smartUploadServlet.do</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>SmartDownloadServlet</servlet-name>
    <url-pattern>/smartDownloadServlet.do</url-pattern>
  </servlet-mapping>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app></span>
action方法:
<span style="font-size:18px;">package com.lihf.action;

import java.io.File;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class FileUploadAction extends ActionSupport {

	private List<File> upload;
	private List<String> uploadContentType;
	private List<String> uploadFileName;
	private String result;
	public List<File> getUpload() {
		return upload;
	}
	public void setUpload(List<File> upload) {
		this.upload = upload;
	}
	public List<String> getUploadContentType() {
		return uploadContentType;
	}
	public void setUploadContentType(List<String> uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	public List<String> getUploadFileName() {
		return uploadFileName;
	}
	public void setUploadFileName(List<String> uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
	public String getResult() {
		return result;
	}
	public void setResult(String result) {
		this.result = result;
	}
	@Override
	public String execute() throws Exception {
		String path = ServletActionContext.getServletContext().getRealPath("/images");
		File file = new File(path);
		if(!file.exists()){
			file.mkdir();
		}
		for(int i=0;i<upload.size();i++){			
			FileUtils.copyFile(upload.get(i), new File(file,uploadFileName.get(i)));
		}
		result ="上傳成功!";
		return SUCCESS;
	}

}
</span>
下載:

action方法:

<span style="font-size:18px;">package com.lihf.action;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class DownLoadAction extends ActionSupport {
	public String inputPath;
	public String fileName;
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public String getInputPath() {
		return inputPath;
	}
	public void setInputPath(String inputPath) {
		this.inputPath = inputPath;
	}
	@Override
	public String execute() throws Exception {
		return SUCCESS;
	}
	public InputStream getInputStream() throws IOException{
		String path = ServletActionContext.getServletContext().getRealPath("/images");
		String filePath = path+"\\"+fileName;
		File file = new File(filePath);
		return FileUtils.openInputStream(file);
		//根據檔案路徑獲取流資訊固定下載檔案使用方法
		//return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
	}
	public String getDownloadFileName(){
		//如果是中文的檔名稱需要轉碼
		String downloadFileName = "";
		try {
			downloadFileName = URLEncoder.encode("檔案下載.jpg","UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return downloadFileName;
	}
}
</span>
jsp頁面:

<a href="download.action?fileName=img3-lg.jpg">檔案下載(圖片)</a>