文章目錄
- 一、檔案上傳
-
- (一)單檔案上傳
- (二)多檔案上傳
- 二、檔案下載下傳
-
- (一)檔案下載下傳的實作方法
- (二)檔案下載下傳的實作過程
- 三、總結
-
- (一)檔案上傳遇到的坎兒
- (二)檔案下載下傳遇到的坑
一、檔案上傳
檔案上傳是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、測試檔案上傳
因為本項目的釋出路徑是在Tomcat中,最後在Tomcat下的webapps中會有上傳的檔案,當Tomcat伺服器關閉時,檔案路徑也會消失。
(二)多檔案上傳
多檔案上傳和單檔案上傳類似,隻需要将檔案上傳頁面改為多檔案上傳,如下:
<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>
二、檔案下載下傳
(一)檔案下載下傳的實作方法
- 通過超連結下載下傳
- 利用程式編碼實作下載下傳
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";
}
②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;
}
③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();
}
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>
三、總結
(一)檔案上傳遇到的坎兒
①顯示上傳空間不夠,改一下配置檔案中最大上傳位元組
②web.xml中若沒有指定springmvc-servlet.xml的初始化位置,則需要将這兩個檔案統一放在webcontent/web-inf下,否則運作時會顯示“這是一個不願公開的資源”(重點,昨天沒注意白花了兩三個小時在找bug)
③若沒有在配置檔案中添加掃描包機制,也可能會出現上述問題
(二)檔案下載下傳遇到的坑
敲重點敲重點敲重點(重要的事情說三遍)
在檔案下載下傳之前一定要确定下載下傳的路徑中存在檔案,否則會有空指針報錯。
道阻且長,人生不易啊!筆落!!!