-> 本文源碼
傳統方式的文件上傳
所需jar包:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
文件上傳的jsp頁面:
<h3>文件上傳</h3>
<form action="user/fileupload" method="post" enctype="multipart/form-data">
選擇文件:<input type="file" name="upload"/><br/>
<input type="submit" value="上傳文件"/>
</form>
這裏需要注意的是:
- form 表單的 enctype 取值必須是: multipart/form-data (默認值是:application/x-www-form-urlencoded)
- method 屬性取值必須是 Post
- 提供一個文件選擇域
文件上傳的Controller控制器:
@Controller
@RequestMapping("/user")
public class UserController {
/**
* 文件上傳
* @return
*/
@RequestMapping("/fileupload1")
public String fileupload1(HttpServletRequest request) throws Exception {
System.out.println("文件上傳...");
// 使用fileupload組件完成文件上傳
// 上傳的位置
String path = request.getSession().getServletContext().getRealPath("/uploads/");
// 判斷,該路徑是否存在
File file = new File(path);
if(!file.exists()){
// 創建該文件夾
file.mkdirs();
}
// 解析request對象,獲取上傳文件項
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析request
List<FileItem> items = upload.parseRequest(request);
// 遍歷
for(FileItem item:items){
// 進行判斷,當前item對象是否是上傳文件項
if(item.isFormField()){
// 說明普通表單向
}else{
// 說明上傳文件項
// 獲取上傳文件的名稱
String filename = item.getName();
// 把文件的名稱設置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
// 完成文件上傳
item.write(new File(path,filename));
// 刪除臨時文件
item.delete();
}
}
return "success";
}
}
測試:
選擇文件上傳後,文件成功存到了本地服務器指定的位置:
SpringMVC普通方式的文件上傳
普通方式,指的是我們上傳的文件和訪問的應用存在於同一臺服務器上。並且上傳完成之後,瀏覽器可能跳轉。
SpringMVC處理的流程:當request到達前端控制器時,調用文件解析器去解析request,解析後返回的是upload這個上傳文件項,其作爲入參傳入controller方法中,相比傳統方式,這樣的方式可以在代碼中省去解析request這一步驟。
jsp頁面:
<h3>Springmvc文件上傳</h3>
<form action="/user/fileupload2" method="post" enctype="multipart/form-data">
選擇文件:<input type="file" name="upload" /><br/>
<input type="submit" value="上傳" />
</form>
SpringMVC框架提供了 MultipartFile 對象,該對象表示上傳的文件,要求變量名稱必須和表單file標籤的name屬性名稱相同,否則無法完成請求參數的綁定。
控制器代碼:
/**
* SpringMVC文件上傳
* @return
*/
@RequestMapping("/fileupload2")
public String fileupload2(HttpServletRequest request, MultipartFile upload) throws Exception {
System.out.println("springmvc文件上傳...");
// 使用fileupload組件完成文件上傳
// 上傳的位置
String path = request.getSession().getServletContext().getRealPath("/uploads/");
// 判斷,該路徑是否存在
File file = new File(path);
if(!file.exists()){
// 創建該文件夾
file.mkdirs();
}
// 說明上傳文件項
// 獲取上傳文件的名稱
String filename = upload.getOriginalFilename();
// 把文件的名稱設置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
// 完成文件上傳
upload.transferTo(new File(path,filename));
return "success";
}
這裏面的關鍵是 **upload.transferTo()**方法。
配置文件解析器:
<!--配置文件解析器對象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760" />
</bean>
測試:
成功上傳:
SpringMVC跨服務器的文件上傳
在實際開發中,我們會有很多處理不同功能的服務器。例如:
應用服務器:負責部署我們的應用
數據庫服務器:運行我們的數據庫
緩存和消息服務器:負責處理大併發訪問的緩存和消息
文件服務器:負責存儲用戶上傳文件的服務器。
(注意:此處說的不是服務器集羣)
我們可以用另一個tomcat服務器作爲圖片服務器,並新建一個web工程部署其上:
修改jsp:
<h3>跨服務器文件上傳</h3>
<form action="/user/fileupload3" method="post" enctype="multipart/form-data">
選擇文件:<input type="file" name="upload" /><br/>
<input type="submit" value="上傳" />
</form>
Controller方法:
/**
* 跨服務器文件上傳
* @return
*/
@RequestMapping("/fileupload3")
public String fileupload3(MultipartFile upload) throws Exception {
System.out.println("跨服務器文件上傳...");
// 定義上傳文件服務器路徑
String path = "http://localhost:9090/uploads/";
// 說明上傳文件項
// 獲取上傳文件的名稱
String filename = upload.getOriginalFilename();
// 把文件的名稱設置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
// 創建客戶端的對象
Client client = Client.create();
// 和圖片服務器進行連接
WebResource webResource = client.resource(path + filename);
// 上傳文件
webResource.put(upload.getBytes());
return "success";
}
409錯誤
在圖片服務器的部署位置新建一個uploads文件夾,否則put時會報409錯誤:
403/405錯誤
在安裝路徑下的/conf/web.xml中修改默認只讀配置,添加readonly並設置爲false:
404錯誤
現在報了404錯誤:
原因:上傳路徑寫錯了
控制層寫的上傳鏈接爲:
“http://localhost:9090/uploads”;
作爲上傳服務器的路徑配置爲:
- 方案一:根據上傳鏈接修改Application context配置,刪除後綴,只保留"/"
Application context:/
- 方案二:根據Application context配置修改上傳鏈接
String path = "http://localhost:9090/SpringMVC_fileUploadServer_war_exploded/uploads";
成功解決: