1.web
上傳文件的必要前提 A form 表單的 enctype 取值必須是: multipart/form-data (默認值是:application/x-www-form-urlencoded) enctype:是表單請求正文的類型 B method 屬性取值必須是 Post C 提供一個文件選擇域<input type=」file」 /> 藉助第三方組件實現文件上傳 使用 Commons-fileupload 組件實現文件上傳,須要導入該組件相應的支撐 jar 包: Commons-fileupload 和 commons-io。 commons-io 不屬於文件上傳組件的開發 jar 文件,但 Commons-fileupload 組件從 1.1 版本開始,它 工做時須要 commons-io 包的支持
1.導入須要的包spring
<!--文件上傳須要的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.5</version> </dependency>
2.代碼數據庫
jsp <h2>文件上傳</h2> <form action="user/fileupload1" method="post" enctype="multipart/form-data"> 選擇文件:<input type="file" name="upload"/><br/> <input type="submit" value="上傳"> </form> 控制器 @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(); //上傳文件 item.write(new File(file, filename)); // 刪除臨時文件 item.delete(); } } return "success"; }
3.結果apache
在項目路徑下的target/項目名/uploads下就會有上傳的文件緩存
SpringMVC框架提供了MultipartFile對象,該對象表示上傳的文件,要求變量名稱必須和表單file標籤的
name屬性名稱相同。 tomcat
在測試傳統方式上傳文件的時候,須要把文件解析器註釋掉服務器
1.原理併發
2.代碼mvc
jsp <h2>springmvc文件上傳</h2> <form action="user/fileupload2" method="post" enctype="multipart/form-data"> 選擇文件:<input type="file" name="upload"/><br/> <input type="submit" value="上傳"> </form> 控制器 //springmvc文件上傳,MultipartFile upload中的upload與表單的文件的name屬性一致 @RequestMapping("/fileupload2") public String fileupload2(HttpServletRequest request, MultipartFile upload) throws Exception { System.out.println("文件上傳..."); // 使用fileupload組件完成文件上傳 // 上傳的位置 String path = request.getSession().getServletContext().getRealPath("/uploads"); // 判斷,該路徑是否存在 File file = new File(path); if (!file.exists()) { // 建立該文件夾 file.mkdirs(); } // 獲取到上傳文件的名稱 String filename = upload.getOriginalFilename(); String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); //上傳的文件名惟一化 filename = uuid + filename; //上傳文件 upload.transferTo(new File(file,filename)); return "success"; } 文件解析器 <!-- 配置文件解析器對象,要求id名稱必須是multipartResolver --> <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"> <property name="maxUploadSize" value="10485760"></property> </bean>
須要用到兩個服務器app
分服務器的目的
在實際開發中,咱們會有不少處理不一樣功能的服務器。例如:
應用服務器:負責部署咱們的應用
數據庫服務器:運行咱們的數據庫
緩存和消息服務器:負責處理大併發訪問的緩存和消息
文件服務器:負責存儲用戶上傳文件的服務器。
(注意:此處說的不是服務器集羣)
分服務器處理的目的是讓服務器各司其職,從而提升咱們項目的運行效率。
這裏須要額外配置一個tomcat服務器,用來模擬圖片服務器
上傳圖片的項目部署到名字爲sprigmvc的tomcat服務器,
另一個空白項目部署到名字爲fileupload的tomcat服務器
兩個服務器的端口號不能相同
新建一個Module,這個項目什麼都不用作,只是用來存文件的
在webapp下建立一個uploads文件夾,等一下將文件上傳到這裏來,修改一下index.jsp,
而後部署到名字叫fileupload的tomcat服務器
測試,沒有問題
導入須要用到的jar包
<!--跨服務器上傳文件須要用到的jar包--> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>1.18.1</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.18.1</version> </dependency>
代碼
jsp <h2>跨服務器文件上傳</h2> <form action="user/fileupload3" method="post" enctype="multipart/form-data"> 選擇文件:<input type="file" name="upload"/><br/> <input type="submit" value="上傳"> </form> 控制器 //跨服務器文件上傳 @RequestMapping("/fileupload3") public String fileupload3(MultipartFile upload) throws Exception { System.out.println("跨服務器文件上傳..."); //定義上傳文件的服務器路徑 String path = "http://localhost:9090/uploads/"; // 獲取到上傳文件的名稱 String filename = upload.getOriginalFilename(); //上傳的文件名惟一化 String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); filename = uuid + filename; //完成文件上傳,跨服務器文件上傳 //建立客戶端的對象 Client client = Client.create(); //和圖片服務器進行鏈接 WebResource webResource = client.resource(path+filename); //上傳文件 webResource.put(upload.getBytes()); return "success"; }
結果,由於代碼中沒有檢測uploadserver的目錄下是否有uploads文件夾,因此須要在對應目錄下建立uploads文件夾
跨服務器上傳可能會遇到的問題
1. 405 Method Not Allowed。 方法不被容許,目標服務器不支持上傳文件。
解決辦法:在文件服務器中配置默認Servlet,並設置初始化參數,修改文件的只讀屬性。在文件服務器中的配置文件web.xml中加入如下代碼:
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>readonly</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
2. 409 Conflict。 文件保存路徑出錯。解決辦法:能夠經過打印代碼中的保存路徑,找到文件服務器下的該路徑,在該路徑下建立uploads文件夾。