文件上傳前表單做的準備
這個在之前學習JSP的時候有接觸到,這裏再次說明一次。
需要把HTML表單的
enctype
屬性設置爲multipart/form-data
需要把HTML表單的
method
屬性設置爲post
需要添加
<input type="file">
字段
文件上傳
Struts2的文件上傳實際上使用的是
commons FileUpload
組件,所以要檢查是否有commons-fileupload-1.4.jar
和commons-io-2.6.jar
這兩個jar包。Struts2進行文件上傳需要使用
FileUpload
攔截器在Action類中定義三個屬性並提供對於的
getter
和setter
方法
文件的File對象:File [fileFieldName]
文件類型:String [fileFieldName]ContentType
文件名:String [fileFieldName]FileName
有了這三個屬性就可以得到文件的基本信息了使用IO流進行文件的上傳
Demo如下:
UploadAction文件:
package com.cerr.struts2.upload;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.ServletContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class UploadAction extends ActionSupport {
private File ppt;
private String pptContentType;
private String pptFileName;
private String pptDesc;
public String getPptDesc() {
return pptDesc;
}
public void setPptDesc(String pptDesc) {
this.pptDesc = pptDesc;
}
public File getPpt() {
return ppt;
}
public void setPpt(File ppt) {
this.ppt = ppt;
}
public String getPptContentType() {
return pptContentType;
}
public void setPptContentType(String pptContentType) {
this.pptContentType = pptContentType;
}
public String getPptFileName() {
return pptFileName;
}
public void setPptFileName(String pptFileName) {
this.pptFileName = pptFileName;
}
@Override
public String execute() throws Exception {
System.out.println(ppt);
System.out.println(pptContentType);
System.out.println(pptFileName);
System.out.println(pptDesc);
ServletContext servletContext = ServletActionContext.getServletContext();
String dir = servletContext.getRealPath("/files/"+pptFileName);
//接下來就io操作
FileOutputStream outputStream = new FileOutputStream(dir);
FileInputStream inputStream = new FileInputStream(ppt);
byte [] buffer = new byte[1024];
int len = 0;
while((len = inputStream.read(buffer))!= -1){
outputStream.write(buffer,0,len);
}
outputStream.close();
inputStream.close();
return super.execute();
}
}
一次上傳多個文件
若傳遞多個文件,則上述提到的三個屬性改爲List
類型並更新其getter
和setter
方法即可,示例:
private List<File> ppt;
private List<String> pptContentType;
private List<String> pptFileName;
private List<String> pptDesc;
返回的是對應的集合
如果上面的Demo要改成上傳多個文件,則只需要把對一個對象的操作改成對一個集合對象的操作即可。
對上傳進行限制
可以通過配置
FileUploadInterceptor
攔截器的參數的方式來進行限制
maximumSize
:上傳的單個文件的最大值,以字節爲單位,默認的最大值爲2M
allowedTypes
:允許的上傳文件的類型,多個類型之間使用逗號分割
allowedExtensions
:允許的上傳文件的擴展名,多個擴展名之間使用逗號分割在
org.apache.struts2
下的default.properties
文件中有對上傳的文件總的大小的限制,名字爲struts.multipart.maxSize
,可以使用常量的方式來修改該限制。上傳的總的大小要注意不能超過該值,在上傳多個文件的時候即使單個滿足,但是總量超了的話,也會出現錯誤,不過不會自動打印出來,該錯誤存在actionError
中,因此可以使用<s:actionerror />
標籤來打印。對於限制條件,可以在國際化資源文件中定義出錯時的錯誤消息
struts.messages.error.uploading
:文件上傳出錯的消息
struts.messages.error.file.too.large
:文件超過最大值的消息
struts.messages.error.content.type.not.allowed
:文件內容類型不合法的消息
struts.messages.error.file.extension.not.allowed
:文件擴展名不合法的消息
對上述的例子進行修改,添加限制
首先在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>
<!-- 配置國際化資源文件 -->
<constant name="struts.custom.i18n.resources" value="i18n"></constant>
<package name="default" namespace="/" extends="struts-default">
<!--自定義攔截器 -->
<interceptors>
<interceptor-stack name="cerrStack">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">2000</param>
<param name="fileUpload.allowedTypes">text/html,text/xml</param>
<param name="fileUpload.allowedExtensions">html,dtd,xml</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 設置我們修改的該攔截器爲默認的攔截器 -->
<default-interceptor-ref name="cerrStack"></default-interceptor-ref>
<action name="testUpload" class="com.cerr.struts2.upload.UploadAction">
<result>/success.jsp</result>
<result name="input">/upload.jsp</result>
</action>
</package>
</struts>
然後在國際化資源文件i18n.properties中定製錯誤消息
struts.messages.error.uploading=\u6587\u4ef6\u4e0a\u4f20\u51fa\u9519\u7684\u6d88\u606f
struts.messages.error.file.too.large=\u6587\u4ef6\u8d85\u8fc7\u6700\u5927\u503c\u7684\u6d88\u606f
struts.messages.error.content.type.not.allowed=\u6587\u4ef6\u5185\u5bb9\u7c7b\u578b\u4e0d\u5408\u6cd5\u7684\u6d88\u606f
struts.messages.error.file.extension.not.allowed=\u6587\u4ef6\u6269\u5c55\u540d\u4e0d\u5408\u6cd5\u7684\u6d88\u606f
這樣就在上面代碼的基礎上添加了上傳文件限制的功能了。
但是這樣的話,實際上定製的消息並不完善,若要修改定製信息,則可以參考org.apache.struts2
下的struts-messages.properties
文件。
文件下載
Struts2中使用
type="stream"
的result進行下載即可。可以爲
stream
的result
設定如下參數
contentType
:結果類型
contentLength
:下載文件的長度
contentDisposition
:設定Content-Disposition響應頭,該響應頭指定響應是一個文件下載類型,一般取值爲attachment;filename=文件名
。
inputName
:指定文件輸入流的getter
定義的那個屬性的名字,默認爲inputStream
bufferSize
:緩存的大小,默認爲1024
allowCaching
:是否允許使用緩存
contentCharSet
:指定下載的字符集以上參數可以在Action中以
getter
方法的方式提供。
配置文件:
<action name="testDownload" class="com.cerr.struts2.upload.DownLoadAction">
<result type="stream">
<param name="bufferSize">2048</param>
</result>
</action>
例子:
package com.cerr.struts2.upload;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.ServletContext;
import java.io.FileInputStream;
import java.io.InputStream;
public class DownLoadAction extends ActionSupport {
private String contentType;
private long contentLength;
private String contentDisposition;
private InputStream inputStream;
public String getContentType() {
return contentType;
}
public long getContentLength() {
return contentLength;
}
public String getContentDisposition() {
return contentDisposition;
}
public InputStream getInputStream() {
return inputStream;
}
@Override
public String execute() throws Exception {
//確定各個成員變量的值
contentType="text/html";
contentDisposition="attachment;filename=aa.png";
ServletContext servletContext = ServletActionContext.getServletContext();
String fileName = null;
fileName = servletContext.getRealPath("/files/1.png");
System.out.println(fileName);
inputStream = new FileInputStream(fileName);
contentLength = inputStream.available();
return super.execute();
}
}