文件上传前表单做的准备
这个在之前学习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();
}
}
网友评论