檔案上傳的幾種方式
阿新 • • 發佈:2018-12-11
一、springmvc中的檔案上傳
1.配置檔案
(1).pom檔案,檔案上傳主要需要如下幾個jar包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
(2)mvc.xml
<?xml version="1.0" encoding="utf-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 開啟包掃描 --> <context:component-scan base-package="controller"/> <!-- 設定配置方案--> <mvc:annotation-driven/> <!-- 檢視解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 檔案上傳解析器:需要注意的是這個bean的id必須是multipartResolver才能被識別,否則會報沒有配置該解析器的錯誤 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"></property> <property name="maxUploadSize" value="10240000"/> </bean> </beans>
(3)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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>uploadmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>uploadmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
2.編寫控制類UploadController.java
第一種,單檔案上傳,使用MultipartFile作為方法引數接收傳入的檔案。
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
* @author: **
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
//檔案上傳
@RequestMapping("/upload")
public String uploadfile(@RequestParam("file") MultipartFile multipartFile) throws IOException {
if(!multipartFile.isEmpty()){
//拼接你想儲存的位置和檔名
String path = "D:/test/"+multipartFile.getOriginalFilename();
//獲得專案路徑即webapp所在路徑,可選
//String pathRoot = request.getSession().getServletContext().getRealPath("");
File tempFile = new File(path);
if (!tempFile.exists()) {
tempFile.mkdirs();
}
try {
multipartFile.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//這裡除了transferTo方法,也可以用位元組流的方式上傳檔案,但是位元組流比較慢,所以還是建議用transferTo
// try {
// //獲取輸出流
// OutputStream os=new FileOutputStream(path);
// //獲取輸入流 CommonsMultipartFile 中可以直接得到檔案的流
// InputStream is=multipartFile.getInputStream();
// byte[] buffer= new byte[1024];
// int len = is.read(buffer);
// while(len!=-1){
// os.write(buffer, 0, len);
// }
// os.flush();
// os.close();
// is.close();
// } catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
//可以用ModelMap或者request請求域來返回上傳路徑
//modelMap.addAttribute("fileUrl", path);
//或者request.setAttribute("fileUrl",path);
return "success";
}
//上傳成功頁面
@RequestMapping("/uploadpage")
public String uploadpage(){
return "upload";
}
}
第二種,單檔案上傳,利用MultipartHttpServletRequest來解析request中的檔案
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
/**
* @author: ***
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
@RequestMapping("/upload")
public ModelMap upload(HttpServletRequest request, ModelMap model) {
// 先例項化一個檔案解析器
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
// 判斷request請求中是否有檔案上傳
if (commonsMultipartResolver.isMultipart(request)) {
// 轉換request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 獲得檔案
MultipartFile file = multiRequest.getFile("file");
if (!file.isEmpty()) {
//上傳路徑
String path = "D:/test/"+file.getOriginalFilename();
// 建立檔案例項
File tempFile = new File(path);
if (!tempFile.exists()) {
tempFile.mkdir();
}
try {
//同樣可以用流檔案方式上傳檔案
file.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//返回上傳路徑,方法一
model.addAttribute("fileUrl", path);
// 方法二:Request域屬性
// request.setAttribute("fileUrl", path);
}
}
return model;
}
}
第三種是多檔案上傳,傳入引數是陣列或者request,多檔案只是需要將上傳的單個檔案從陣列或者request中遍歷出來,然後進行單檔案上傳操作。
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author: ***
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
/**
* 多檔案上傳,方式一:利用MultipartFile[]作為方法的引數接收傳入的檔案
* 用 transferTo方法來儲存圖片,儲存到本地磁碟。
* @author chunlynn
*/
@RequestMapping("/upload")
public ModelMap upload3(@RequestParam("file") MultipartFile[] files, ModelMap model) {
List<String> fileUrlList = new ArrayList<String>(); //用來儲存檔案路徑
// 先判斷檔案files不為空
if (files != null && files.length > 0) {
for (MultipartFile file : files) { //迴圈遍歷取出單個檔案
if (!file.isEmpty()) {
String fileName = file.getOriginalFilename();
String path = "D:/test/"+fileName; //這裡D:/test/可以修改為自己的路徑,也可以對fileName進行修改。
// 建立檔案例項
File tempFile = new File(path);
//判斷父級資料夾是否存在
if (!tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdir();
}
if (!tempFile.exists()) {
tempFile.mkdir();
}
try {
//這裡也可以用流實現
file.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fileUrlList.add(path);
}
}
// 方法一:model屬性儲存圖片路徑
model.addAttribute("fileUrlList", fileUrlList);
// 方法二:request域屬性儲存圖片路徑
// request.setAttribute("fileUrlList", fileUrlList);
}
return model;
}
/**
* 多檔案上傳,方式二:利用MultipartHttpServletRequest來解析Request中的檔案
*/
@RequestMapping("/upload2")
public ModelMap upload2(HttpServletRequest request,ModelMap model) {
List<String> fileUrlList = new ArrayList<>(); //用來儲存檔案路徑
// 先例項化一個檔案解析器
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
// 判斷request請求中是否有檔案上傳
if (commonsMultipartResolver.isMultipart(request)) {
// 轉換Request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 獲得檔案,方式一
List<MultipartFile> files = multiRequest.getFiles("file");
for (MultipartFile file : files) { //迴圈遍歷取出單個檔案上傳
if (!file.isEmpty()) {
// 獲得原始檔名,拼接需要上傳的位置得到路徑
String fileName = file.getOriginalFilename();
String path = "D:/test/"+fileName;
// 建立檔案例項
File tempFile = new File(path); //檔案儲存路徑為pathRoot + path
if (!tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdir();
}
if (!tempFile.exists()) {
tempFile.mkdir();
}
try {
//也可用流的方式上傳
file.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fileUrlList.add(path);
}
}
model.addAttribute("fileUrlList", fileUrlList);
// 方法二:request域屬性儲存
// request.setAttribute("fileUrlList", fileUrlList);
}
return model;
}
}
檔案下載,在這裡我是寫死了檔案的下載路徑和下載檔名的,實際專案中,這兩個欄位下載路徑一般會配置在配置檔案中,下載檔案的名稱則是前臺通過request傳遞到後臺的,所以這個可以將這兩個欄位作為傳入引數,寫成介面。
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
/**
* @author: ***
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
/**
* 檔案下載功能
* @param request
* @param response
* @throws Exception
*/
@RequestMapping("/down")
public void down(HttpServletRequest request,HttpServletResponse response) throws Exception{
String downloadpath = "D:/test/"; //這是你儲存你需要下載的檔案所在的位置的路徑
//test.txt為需要下載的檔案的全檔名
String fileName = "test.txt";
String path = downloadpath+fileName;
//獲取輸入流
InputStream is = new BufferedInputStream(new FileInputStream(new File(path)));
//這裡是下載檔案的時候,如果你對下載檔案重新命名的名字
String filename = "下載檔案.txt";
//轉碼,防止檔名中文亂碼
filename = URLEncoder.encode(filename,"UTF-8");
//設定檔案下載頭
response.addHeader("Content-Disposition", "attachment;filename=" + filename);
//1.設定檔案ContentType型別,這樣設定,會自動判斷下載檔案型別
response.setContentType("multipart/form-data");
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
int len = is.read();
while((len!= -1){
out.write(len);
out.flush();
}
out.close();
}
}
3.頁面
upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>檔案上傳頁</title>
</head>
<body>
<form action="/mvc/test/upload" method="post" enctype="multipart/form-data">
<label>上傳檔案</label>
<input type="file" name="file">
<input type="submit" value="提交">
</form>
</body>
</html>
注意,form表單裡,enctype="multipart/form-data",一定要配置。action是你方法的訪問路徑,由於我在tomcat中配置了專案訪問名稱是mvc,所以我這裡的路徑會是“/mvc/test/upload”,具體路徑由個人的配置而定。
還有個上傳成功的提示頁,自己寫一個就行,不貼程式碼了。