在之前的隨筆之中,我們已經了解Java通過上傳組件來實現上傳和下載,這次我們來了解Struts2的上傳和下載。
注意:文件上傳時,我們需要將表單提交方式設置為"POST"方式,並且將enctype屬性設置為"multipart/form-data",該屬性的默認值為"application/x-www-form-urlencoded",就是說,表單要寫成以下這種形式:
<form action="" method="post" enctype="multipart/form-data"></form>
而且Struts2中並沒有提供自己的文件上傳解析器,默認使用的是Jakarta的Common-FileUpload的文件上傳組件,所以我們還需要在添加兩個包:
commons-io
commons-fileupload
至於版本根據自己需要選擇(筆者在第一篇已經搭建好環境了。地址)
注意點如下:
1.1、文件上傳的前提是表單屬性method="post" enctype="multipart/form-data";
1.2、web應用中必須包含common-fileupload.jar和common-io.jar,因為struts2默認上傳解析器使用的是jakarta;
1.3、可以在struts.xml中配置最大允許上傳的文件大小:<constant name="struts.multipart.maxSize" value="....."/>,默認為2M;
2.1、在Action中定義屬性:
private File upload; //包含文件內容
private String uploadFileName; //上傳文件的名稱;
private String uploadContentType; //上傳文件的MIME類型;
這些屬性都會隨著文件的上傳自動賦值;
2.2、上傳圖片的例子
新建視圖界面:Upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Struts2 FileUpload</title> </head> <body> <form action="fileupload" method="post" enctype="multipart/form-data"> 文件標題:<input type="text" name="title"/><br/> 選擇文件:<input type="file" name="upload"/><br/> <input type="submit" value="上傳"/> </form> </body> </html>
新建UploadAction繼承ActionSupport
package com.Struts2.load; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; //上傳單個文件 public class UploadAction extends ActionSupport { //文件標題請求參數的屬性 private String title; //上傳文件域的屬性 private File upload; //上傳文件類型 private String uploadContentType; //上傳文件名 private String uploadFileName; //接受依賴注入的屬性 private String savePath; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadContentType() { return uploadContentType; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } //返回上傳文件的保存位置 public String getSavePath() { return ServletActionContext.getRequest().getRealPath(savePath); } //接受依賴注入的方法 public void setSavePath(String savePath) { this.savePath = savePath; } public String execute() throws Exception{ System.out.println(getSavePath()); System.out.println(getUploadFileName()); //以服務器的文件保存地址和原文件名建立上傳文件輸出流 FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadFileName()); //以上傳文件建立一個文件上傳流 FileInputStream fis = new FileInputStream(getUpload()); //將上傳文件的內容寫入服務器 byte[] buffer = new byte[1024]; int leng = 0; while((leng=fis.read(buffer))>0){ fos.write(buffer,0,leng); buffer = new byte[1024]; } return SUCCESS; } }
struts.xml配置文件中部署
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!--文件上傳 --> <package name="default" extends="struts-default"> <action name="fileupload" class="com.Struts2.load.UploadAction"> <!--使用攔截器過濾:1、配置默認攔截器,2、配置input的邏輯視圖--> <interceptor-ref name="fileUpload"> <param name="allowedTypes">image/jpeg,image/jpg,/image/gif,image/png</param> </interceptor-ref> <!-- 必須顯示配置defaultStack攔截器的引用 --> <interceptor-ref name="defaultStack"/> <param name="savePath">/upload</param> <result name="success">succ.jsp</result> <!--必須配置input的邏輯視圖 --> <result name="input">Error.jsp</result> </action> <struts>
注意:web.xml中需要配置struts2的攔截器
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>LearStruts2</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!--為Struts2定義一個過濾器 --> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>web.xml
succ.jsp視圖代碼
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>上傳成功</title> </head> <body> 上傳成功<br/> 文件標題:<s:property value="title"/><br/> <s:property value="uploadFileName"/> 文件為:<img src="<s:property value="'/LearStruts2/upload/'+uploadFileName"/>"/><br/> </body> </html>
Error.jsp視圖代碼
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Error 界面</title> </head> <body> <s:fielderror/> </body> </html>Error.jsp
代碼效果如下:
注意:在struts.xml配置文件中,已經限制只能上傳圖片格式,如果上傳別的文件的話,則會報錯。
2.3、多個文件上傳
新建Upliads.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>上傳多個文件</title> </head> <body> <form action="filesupload" method="post" enctype="multipart/form-data"> 文件標題:<input type="text" name="title"><br/> 選擇第一個文件:<input type="file" name="uploads"><br/> 選擇第二個文件:<input type="file" name="uploads"><br/> 選擇第三個文件:<input type="file" name="uploads"><br/> <input type="submit" value="上傳"/> </form> </body> </html>Upliads.jsp
新建UploadsAction類繼承ActionSupport
package com.Struts2.load; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; //上傳多個文件 public class UploadsAction extends ActionSupport { private String title; //對應jsp的title private File[] uploads; //對應jsp的uploads private String[] uploadsContentType; private String[] uploadsFileName; //savePath:通過配置文件進行賦值"'\'upload", //其中的'\'表示項目的根目錄D:\\tomcat-8.0\\wtpwebapps\\LearStruts2\\upload private String savePath; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public File[] getUploads() { return uploads; } public void setUploads(File[] upload) { this.uploads = upload; } public String[] getUploadsContentType() { return uploadsContentType; } public void setUploadsContentType(String[] uploadsContentType) { this.uploadsContentType = uploadsContentType; } public String[] getUploadsFileName() { return uploadsFileName; } public void setUploadsFileName(String[] uploadsFileName) { this.uploadsFileName = uploadsFileName; } public String getSavePath() { return ServletActionContext.getRequest().getRealPath(savePath); } public void setSavePath(String savePath) { this.savePath = savePath; } public String execute() throws Exception{ File[] files = getUploads(); for(int i = 0;i<files.length;i++){ System.out.println(getSavePath()); System.out.println(getUploadsFileName()[i]); //getSavePath : 獲得根目錄 //getUploadsFileName() : 獲得文件名 FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadsFileName()[i]); FileInputStream fis = new FileInputStream(files[i]); byte[] buffer = new byte[1024]; int len = 0; while((len=fis.read(buffer))>0){ fos.write(buffer,0,len); buffer = new byte[1024]; } } return SUCCESS; } }
struts.xml中配置信息
<!--多個文件上傳 --> <action name="filesupload" class="com.Struts2.load.UploadsAction"> <!--該屬性是依賴注入:通過配置文件給savePath賦值 ,是必須的 --> <param name="savePath">/upload</param> <result name="success">succ1.jsp</result> </action>
succ1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>多個文件上傳</title> </head> <body> 上傳成功 </body> </html>succ1.jsp
代碼效果如下:
2.3、Struts2的文件下載
視圖下載界面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Struts 2實現的文件下載</title> </head> <body> <a href="down.action">圖片下載</a> </body> </html>fuledown.jsp
Action類
package com.Struts2.load; import java.io.InputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class DownAction extends ActionSupport { private String inputPath; private String contentType; private String filename; public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public String getInputPath() { return inputPath; } public void setInputPath(String inputPath) { this.inputPath = inputPath; } //下載用的Action應該返回一個InputStream實例 //該方法對應在result裡的inputName屬性值為targetFile //第二步 public InputStream getTargetFile() throws Exception{ System.out.println("1"); InputStream in=ServletActionContext.getServletContext().getResourceAsStream(inputPath); return in; } //第一步 public String execute(){ System.out.println("???"); inputPath="/upload/1.jpg";//要下載的文件名稱 filename="1.jpg"; //保存文件時的名稱 contentType="image/jpg";//保存文件的類型 return SUCCESS; } }
Struts.xml配置文件
<!-- 下載文件的Action --> <action name="down" class="com.Struts2.load.DownAction"> <!-- 指定被下載資源的位置 --> <param name="inputPath">${inputPath}</param> <!-- 配置結果類型為stream的結果 --> <result name="success" type="stream"> <!-- contentType:指定下載文件的類型 ,和互聯網MIME標准中的規定類型一致, 例如text/plain代表純文本,text/xml表示XML,image/gif代表GIF圖片,image/jpeg代表JPG圖片 --> <param name="contentType">${contentType}</param> <!-- 指定下載文件的位置 --> <!-- inputName:下載文件的來源流,對應著action類中某個類型為Inputstream的屬性名, 例如取值為inputStream的屬性需要編寫getInputStream()方法 --> <param name="inputName">targetFile</param> <!-- contentDisposition 文件下載的處理方式,包括內聯(inline)和附件(attachment)兩種方式, 而附件方式會彈出文件保存對話框,否則浏覽器會嘗試直接顯示文件。 默認情況是代表inline,浏覽器會嘗試自動打開它 --> <param name="contentDisposition">attachement;filename="${filename}"</param> <!-- 指定下載文件的緩沖大小 --> <param name="bufferSize">50000000</param> </result> </action>
代碼都有筆者測試過,至於解析,筆者會在後期理解好之後再重新寫。