天天看點

SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

文章目錄

  • 一、檔案上傳
    • (一)單檔案上傳
    • (二)多檔案上傳
  • 二、檔案下載下傳
    • (一)檔案下載下傳的實作方法
    • (二)檔案下載下傳的實作過程
  • 三、總結
    • (一)檔案上傳遇到的坎兒
    • (二)檔案下載下傳遇到的坑

一、檔案上傳

檔案上傳是WEB經常面對的問題,對于Java應用主要有以下三種上傳檔案的方式

  • 檔案流手工程式設計
  • 基于commons-fileupload的元件
  • 基于servlet3的檔案上傳

(一)單檔案上傳

1、建立應用導入jar包

  • Spring MVC相關jar包
  • commons-fileupload元件相關jar包
  • JSTL的相關jar包

2、建立web.xml檔案

配置DispatcherServlet和添加字元編碼過濾器
<!--配置DispatcherServlet -->
	<servlet>
		<servlet-name>Springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	<!-- 避免中文亂碼 -->
	<filter>
    	<filter-name>characterEncodingFilter</filter-name>
    	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    	<init-param>
      		<param-name>encoding</param-name>
      		<param-value>UTF-8</param-value>
    	</init-param>
    	<init-param>
     		 <param-name>forceEncoding</param-name>
      		<param-value>true</param-value>
    	</init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

           

3、建立檔案上傳頁面

1、設定methon屬性為post

2、 enctype屬性為multipart/form-data,該編碼方式表明伺服器以二進制流的方式來處理表單資料,并将檔案内容封裝到請求參數裡

3、表單屬性multiple設定為multiple,可同時上傳多個檔案

<form action="${pageContext.request.contextPath }/onefile" method="post"
		enctype="multipart/form-data">
		選擇檔案:<input type="file" name="myfile" multiple="multiple"/><br>
		檔案描述:<input type="text" name="description"/><br>
		<input type="submit" value="送出"/>	
	</form>
           

4、建立pojo類

領域模型中的屬性名對應檔案上傳界面的file類型的表單參數名

public class FileDomain {

	private String description;
	private List<MultipartFile> myfile;
	//省略getter和setter方法
}
           

5、建立控制器類

@Controller
public class FileUploadController {
	private static final Log Logger = LogFactory.getLog(FileUploadController.class);
	@RequestMapping("/onefile")
	public String oneFileUpload(@ModelAttribute FileDomain fileDomain,HttpServletRequest request) {
		
//		指定文檔上傳的路徑,本項目的釋出路徑是在tomcat下的webapps目錄中
		String realPath = request.getServletContext().getRealPath("/uploadfiles/");
//		如果檔案夾不存在則建立
		File targetDir = new File(realPath);
		if(!targetDir.exists()) {
			targetDir.mkdirs();
		}
//		獲得上傳的檔案集
		List<MultipartFile> files = fileDomain.getMyfile();	
		for(MultipartFile file:files) {
			String filename = file.getOriginalFilename();
			File targetFile = new File(realPath,filename);
			System.out.println("目标檔案為:"+targetFile);
//			開始檔案上傳
			try {
//				使用MultipartFile接口方法完成檔案上傳到指定位置
				file.transferTo(targetFile);
				Logger.info("檔案上傳成功!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return "showone";
	}
}
           

6、建立springmvc-servlet.xml配置檔案

1、添加掃描機制

2、配置視圖解析器

3、使用spring的commonMultipartResolver,id必須為internalResourceViewResolver

<!-- 使用掃描機制掃描控制器類 -->
	<context:component-scan base-package="Controller"></context:component-scan>
	<!-- 配置視圖解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
			id="internalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"	>
		<property name="defaultEncoding" value="UTF-8"></property>
		<property name="maxUploadSize" value="5400000000"></property>
		<property name="uploadTempDir" value="fileUpload/temp"></property>
	</bean>
           

7、建立成功顯示界面

運用JSTL的核心标簽庫,需要在報頭上添加

<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c” %>

<body>
	${fileDomain.description }<br>
	<!-- fileDomain.getMyfile().getOriginalFilename() -->
	<c:forEach  items="${fileDomain.myfile }" varStatus="loop">
		檔案名稱:${fileDomain.myfile[loop.count-1].originalFilename }<br>
	</c:forEach>
</body>
           

8、測試檔案上傳

SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結
SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

因為本項目的釋出路徑是在Tomcat中,最後在Tomcat下的webapps中會有上傳的檔案,當Tomcat伺服器關閉時,檔案路徑也會消失。

SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

(二)多檔案上傳

多檔案上傳和單檔案上傳類似,隻需要将檔案上傳頁面改為多檔案上傳,如下:

<body>
	<form action="${pageContext.request.contextPath }/multipFiles" method="post"
		enctype="multipart/form-data">
		選擇檔案1:<input type="file" name="myfile" multiple="multiple"/><br>
		檔案描述1:<input type="text" name="description"/><br>
		選擇檔案2:<input type="file" name="myfile" multiple="multiple"/><br>
		檔案描述2:<input type="text" name="description"/><br>
		選擇檔案3:<input type="file" name="myfile" multiple="multiple"/><br>
		檔案描述3:<input type="text" name="description"/><br>
		<input type="submit" value="送出"/>	
	</form>
</body>
           
SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結
SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

二、檔案下載下傳

(一)檔案下載下傳的實作方法

  • 通過超連結下載下傳
  • 利用程式編碼實作下載下傳

1、利用超連結下載下傳簡單,但是暴露了下載下傳檔案的真實位置,并且隻能下載下傳存放在Web應用程式所在目錄下的檔案,具有一定的局限性

2、利用程式編碼下載下傳可以增加安全通路機制,還可以從任意位置提供下載下傳的資料,即可以将檔案存放在Web應用程式之外的目錄中,也可以将檔案儲存到資料庫。但實作較第一種下載下傳略顯困難。

利用程式實作下載下傳需要設定兩個報頭:

response.setHeader("Content-Type", "application/x-msdownload");
response.setHeader("Content-Disposition", "attachment; filename="+filename);
           

(二)檔案下載下傳的實作過程

在執行檔案下載下傳時,需保證,對應的檔案目錄存在檔案,否則會報錯

1、編寫控制器類

1、showDownloadFiles方法擷取可下載下傳的檔案名稱。
2、down方法執行下載下傳功能。
3、toUTF8String方法是下載下傳儲存時中文檔案字元編碼轉換,不出現亂碼。
           

①showDownloadFiles方法

//	用于顯示檔案
	private String showDownloadFiles(Model model,HttpServletRequest request) {
//		獲得文檔下載下傳的路徑
		String realpath = request.getServletContext().getRealPath("/uploadfiles");
//		擷取下載下傳的檔案
		File dir = new File(realpath);
		File file[] = dir.listFiles();
		System.out.println(file);
 		ArrayList<String> filenames = new ArrayList<String>();
		for(int i = 0;i<file.length;i++) {
			filenames.add(file[i].getName());
		}
		model.addAttribute("files", filenames);
		return "showDownloadFiles";
	}
           
SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

②down方法

@RequestMapping("down")
	private String down(@RequestParam String filename,
						HttpServletRequest request,HttpServletResponse response) {
		String filepath = null;
		InputStream in = null;
		ServletOutputStream out = null;
		try {
//			獲得檔案下載下傳的路徑
			filepath = request.getServletContext().getRealPath("/uploadfiles");
//			設定檔案下載下傳時的報頭
			response.setHeader("Content-Type", "application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename="+
            				toUTF8String(filename));
//          讀入檔案
            in = new FileInputStream(filepath+"\\"+filename);
//          獲得響應對象的輸出流,用于向用戶端輸出二進制資料
            out = response.getOutputStream();
            out.flush();
            int ahead = 0;
            byte b[] = new byte[1024];
            while ((ahead = in.read(b)) != -1 & in != null) {
				out.write(b, 0, ahead);
			}
            out.flush();
            in.close();
            out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		logger.info("檔案下載下傳成功");
		return null;
	}
           
SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

③toUTF8String方法

//	下載下傳檔案時中文檔案字元編碼的轉換
	private String toUTF8String(String str) {
		StringBuffer sb = new StringBuffer();
		int len = str.length();
		for(int i = 0; i < len; i++){
			//取出字元中的每個字元
			char c = str.charAt(i);
			//Unicode碼值在0-255之間,不作處理
			if(c >= 0 && c <= 255){
				sb.append(c);
			}else{//轉換UTF-8編碼
				byte b[];
				try {
					b = Character.toString(c).getBytes("UTF-8");
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					b = null;
				}
				//轉換為%HH的字元串形式
				for(int j = 0; j < b.length; j ++){
					int k = b[j];
					if(k < 0){
						k &= 255;
					}
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}
           
SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

2、建立檔案清單顯示頁面

這裡同樣用到了JSTL标簽庫

<body>
	<table>
		<tr><td>可下載下傳的檔案名</td></tr>
		<c:forEach var="filename" items="${files }">
			<tr>
				<td>
				<a href="${pageContext.request.contextPath }/down?filename=${filename}">${filename}</a>
				</td>
			</tr>
		</c:forEach>
	</table>
</body>
           

三、總結

(一)檔案上傳遇到的坎兒

①顯示上傳空間不夠,改一下配置檔案中最大上傳位元組

SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

②web.xml中若沒有指定springmvc-servlet.xml的初始化位置,則需要将這兩個檔案統一放在webcontent/web-inf下,否則運作時會顯示“這是一個不願公開的資源”(重點,昨天沒注意白花了兩三個小時在找bug)

SpringMVC之檔案上傳下載下傳一、檔案上傳二、檔案下載下傳三、總結

③若沒有在配置檔案中添加掃描包機制,也可能會出現上述問題

(二)檔案下載下傳遇到的坑

敲重點敲重點敲重點(重要的事情說三遍)

在檔案下載下傳之前一定要确定下載下傳的路徑中存在檔案,否則會有空指針報錯。

道阻且長,人生不易啊!筆落!!!