struts2 文件上傳下載
四、文件的上傳(攔截器)和下載(stream結果類型)(需要練一遍)
1、文件上傳
必要前提:
a.表單method必須是post;
b.enctype取值必須是multipart/form-data;
c.提供文件選擇域。
1 <%@ page language="java" import="java.util.*"upload1.jsppageEncoding="UTF-8"%> 2 <%@ taglib uri="/struts-tags" prefix="s" %> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>struts2中的文件上傳</title> 7 </head> 8 <body> 9 <%--文件上傳的必要前提: 10 1.請求方式必須是post11 2.enctype屬性的取值必須是multipart/form-data 12 3.提供一個文件選擇域 13 --%> 14 <s:actionerror/> 15 <s:form action="upload.action" enctype="multipart/form-data"> 16 <s:textfield name="username" label="用戶名" /> 17 <s:file name="photo" label="照片" /> 18 <s:submit value="上傳"/> 19 </s:form> 20 </body> 21 </html>
動作類:
1 /** 2 * struts2文件上傳的入門案例 3 * @author zhy 4 * 5 */ 6 public class UploadAction extends ActionSupport { 7 8 //表單上提供的字段 9 private String username; 10 private File photo; 11 //struts2在文件上傳時提供的屬性 12 private String photoFileName;//上傳的文件名。上傳字段名稱+FileName 註意大小寫 13 private String photoContentType;//上傳文件的MIME類型。上傳字段名稱+ContentType 註意大小寫 14 15 16 public String upload(){ 17 //1.拿到ServletContext 18 ServletContext application = ServletActionContext.getServletContext(); 19 //2.調用realPath方法,獲取根據一個虛擬目錄得到的真實目錄 20 String filePath = application.getRealPath("/WEB-INF/files"); 21 //3.如果這個真實的目錄不存在,需要創建 22 File file = new File(filePath); 23 if(!file.exists()){ 24 file.mkdirs(); 25 } 26 //4.把photo存過去 27 //拷貝:把photo的臨時文件復制到指定的位置。註意:臨時文件還在 28 //FileUtils.copyFile(photo, new File(file,photoFileName)); 29 30 //剪切:把臨時文件剪切指定的位置,並且給他重命名。 註意:臨時文件沒有了 31 photo.renameTo(new File(file,photoFileName)); 32 33 return null; 34 } 35 36 37 public String getUsername() { 38 return username; 39 } 40 41 42 public void setUsername(String username) { 43 this.username = username; 44 } 45 46 47 public File getPhoto() { 48 return photo; 49 } 50 51 52 public void setPhoto(File photo) { 53 this.photo = photo; 54 } 55 56 57 public String getPhotoFileName() { 58 return photoFileName; 59 } 60 61 62 public void setPhotoFileName(String photoFileName) { 63 this.photoFileName = photoFileName; 64 } 65 66 67 public String getPhotoContentType() { 68 return photoContentType; 69 } 70 71 72 public void setPhotoContentType(String photoContentType) { 73 this.photoContentType = photoContentType; 74 } 75 76 77 }uploadAction1.java
2、文件上傳的配置
2.1、文件上傳大小限制(默認是2MB)
如果上傳文件超過了默認大小,upload攔截器會轉向一個input的邏輯視圖。
如果 input視圖返回了登陸頁面, 可以使用<s:actionerror/> 回顯錯誤信息
a、改變上傳文件大小限制:
思路1:給Struts2的攔截器註入參數:(行不通)
思路2:在struts.xml中改變default.properties文件中的常量。
1 <!-- 配置全局消息資源包 --> 2 <constant name="struts.custom.i18n.resources" value="com.itheima.web.action.fileupload_message"></constant> 3 <!-- 限制上傳文件的大小,第一種方式:通過修改struts2的常量。 4 在default.properties中配的struts.multipart.maxSize=2097152--> 5 <constant name="struts.multipart.maxSize" value="5242880"></constant> 6 <package name="p1" extends="struts-default"> 7 <action name="upload" class="com.itheima.web.action.UploadAction" method="upload"> 8 <!-- 第二種方式:通過給fileUpload的攔截器註入參數的形式,控制上傳文件的大小 9 無法使用 <param name="fileUpload.maximumSize">31457280</param>--> 10 <interceptor-ref name="defaultStack"> 11 <!-- 限制上傳文件的擴展名。如果有多個,使用逗號分隔 12 <param name="fileUpload.allowedExtensions">jpg,png,bmp</param>--> 13 <!-- 限制上傳文件的MIME類型。 如果有多個,使用逗號分隔 --> 14 <param name="fileUpload.allowedTypes">image/jpg,image/pjpeg,image/png</param> 15 </interceptor-ref> 16 <result name="input">/upload1.jsp</result> 17 </action>struts.xml
2.2、限制文件上傳的類型
a、通過限制上傳文件的擴展名
思路:給fileUpload攔截器註入參數
當上傳非限定擴展名時:有如下錯誤提示(英文提示)
b、通過限制上傳文件的MIME類型
當上傳非限定MIME類型時:有如下錯誤提示(英文提示)
<!-- 配置全局消息資源包 --> <constant name="struts.custom.i18n.resources" value="com.itheima.web.action.fileupload_message"></constant> <!-- 限制上傳文件的大小,第一種方式:通過修改struts2的常量。 在default.properties中配的struts.multipart.maxSize=2097152--> <constant name="struts.multipart.maxSize" value="5242880"></constant> <package name="p1" extends="struts-default"> <action name="upload" class="com.itheima.web.action.UploadAction" method="upload"> <!-- 第二種方式:通過給fileUpload的攔截器註入參數的形式,控制上傳文件的大小 無法使用 <param name="fileUpload.maximumSize">31457280</param>--> <interceptor-ref name="defaultStack"> <!-- 限制上傳文件的擴展名。如果有多個,使用逗號分隔 <param name="fileUpload.allowedExtensions">jpg,png,bmp</param>--> <!-- 限制上傳文件的MIME類型。 如果有多個,使用逗號分隔 --> <param name="fileUpload.allowedTypes">image/jpg,image/pjpeg,image/png</param> </interceptor-ref> <result name="input">/upload1.jsp</result> </action>strut.xml
3、出錯後的錯誤信息中文提示(Struts2中的所有文本提示都是基於國際化的)
默認信息提示在:struts2-core.jar\org.apache.struts2\struts-message.properties
解決辦法:用國際化消息資源包,把對應的key取值改為中文即可。
常用的key值:
4、多文件上傳
jsp頁面:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib uri="/struts-tags" prefix="s" %> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>struts2中的多文件上傳</title> 7 </head> 8 <body> 9 <%--文件上傳的必要前提: 10 1.請求方式必須是post 11 2.enctype屬性的取值必須是multipart/form-data 12 3.提供一個文件選擇域 13 --%> 14 <s:actionerror/> 15 <s:form action="upload1.action" enctype="multipart/form-data"> 16 <s:textfield name="username" label="用戶名" /> 17 <s:file name="photo" label="照片" /> 18 <s:file name="photo" label="照片" /> 19 <s:submit value="上傳"/> 20 </s:form> 21 </body> 22 </html>upload2.jsp
配置文件:
1 <action name="upload1" class="com.itheima.web.action.UploadAction1" method="upload"> 2 <result name="input">/upload2.jsp</result> 3 </action>struts.xml
動作類:
1 /** 2 * struts2文件上傳的入門案例 3 * @author zhy 4 * 5 */ 6 public class UploadAction1 extends ActionSupport { 7 8 //表單上提供的字段 9 private String username; 10 private File[] photo; 11 //struts2在文件上傳時提供的屬性 12 private String[] photoFileName;//上傳的文件名。上傳字段名稱+FileName 註意大小寫 13 private String[] photoContentType;//上傳文件的MIME類型。上傳字段名稱+ContentType 註意大小寫 14 15 16 public String upload(){ 17 //1.拿到ServletContext 18 ServletContext application = ServletActionContext.getServletContext(); 19 //2.調用realPath方法,獲取根據一個虛擬目錄得到的真實目錄 20 String filePath = application.getRealPath("/WEB-INF/files"); 21 //3.如果這個真實的目錄不存在,需要創建 22 File file = new File(filePath); 23 if(!file.exists()){ 24 file.mkdirs(); 25 } 26 //4.把photo存過去 27 //剪切:把臨時文件剪切指定的位置,並且給他重命名。 註意:臨時文件沒有了 28 for(int i=0;i<photo.length;i++){ 29 photo[i].renameTo(new File(file,photoFileName[i])); 30 } 31 32 return null; 33 } 34 35 36 public String getUsername() { 37 return username; 38 } 39 40 41 public void setUsername(String username) { 42 this.username = username; 43 } 44 45 46 public File[] getPhoto() { 47 return photo; 48 } 49 50 51 public void setPhoto(File[] photo) { 52 this.photo = photo; 53 } 54 55 56 public String[] getPhotoFileName() { 57 return photoFileName; 58 } 59 60 61 public void setPhotoFileName(String[] photoFileName) { 62 this.photoFileName = photoFileName; 63 } 64 65 66 public String[] getPhotoContentType() { 67 return photoContentType; 68 } 69 70 71 public void setPhotoContentType(String[] photoContentType) { 72 this.photoContentType = photoContentType; 73 } 74 75 }uploadAction2.java
5、文件下載:其實就是一種結果類型(Stream)
動作類:
1 /** 2 * 文件下載 3 * @author zhy 4 * 5 */ 6 public class DownloadAction extends ActionSupport { 7 8 //註意:在給InputSteam指定名稱時,不能使用in 9 private InputStream inputStream; 10 //創建一個文件名的屬性 11 private String filename; 12 13 public String download()throws Exception{ 14 //1.找到文件的存儲路徑 15 String filePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/5.jpg"); 16 //2.把文件讀到一個InputStream中 17 inputStream = new FileInputStream(filePath); 18 19 //在返回之前,給filename賦值 20 filename="照片.jpg"; 21 22 //3.返回一個成功 23 return SUCCESS; 24 //4.由一個叫做stream的結果類型為我們把剩下的事情做完。 25 } 26 27 public InputStream getInputStream() { 28 return inputStream; 29 } 30 31 public void setInputStream(InputStream inputStream) { 32 this.inputStream = inputStream; 33 } 34 35 public String getFilename() { 36 return filename; 37 } 38 39 public void setFilename(String filename) { 40 this.filename = filename; 41 } 42 43 44 45 46 }downLoad
配置文件:
1 <action name="download" class="com.itheima.web.action.DownloadAction" method="download"> 2 <result name="success" type="stream"> 3 <!-- 給stream的結果類型註入參數:Content-Type --> 4 <param name="contentType">application/octet-stream</param> 5 <!-- 告知客戶瀏覽器以下載的方式打開 6 <param name="contentDisposition">attachment;filename=photo.jpg</param> --> 7 <!-- 使用OGNL表達式,來動態獲取文件名 8 [email protected]@encode(filename,"UTF-8")} 把${}中間的內容當成一個OGNL表達式來看待 9 --> 10 <param name="contentDisposition">attachment;[email protected]@encode(filename,"UTF-8")}</param> 11 <!-- 註入字節輸入流 :取值要寫動作類中set方法的名稱,首字母改成小寫--> 12 <param name="inputName">inputStream</param> 13 </result> 14 </action>struts.xml
問題:文件名不能在配置文件中寫死,需要根據實際情況獲取。
解決辦法:上面的代碼就是處理過後的
struts2 文件上傳下載