目录
Struts 2上传下载
实现文件上传
准备工作,项目中导入两个jar文件:
commons-fileupload-版本.jar
commons-io-版本.jar
官网获取:
①commons-fileupload:http://commons.apache.org/fileupload
②commons-io:http://commons.apache.org/io
Struts 2下获取:根目录下的lib文件夹中
**使用简单:**可以方便地嵌入到JSP问津中,编写少量代码即可完成文件的上传
(1)能够全程控制上传的内容
(2)能够对上传文件的大小、类型进行控制
1. 上传页面准备(设置表单)
<!-- 默认文件上传的文件大小不超过2MB,超过会报错404 -->
<form action="fileUploadAction" method="post" enctype="multipart/form-data">
<!-- Action中以upload为前缀 -->
文件:<input type="file" name="upload" />
<input type="submit" value="上传文件">
</form>
2.开发实现上传的Action
//对应表单的upload <input type="file" name="upload"/>
private File upload;
//当前上传的文件名
private String uploadFileName;
//文件类型(MIME)
private String uploadContentType;
……省略getter、setter方法
@Override
public String execute() throws Exception {
//开始拿到上传的文件,进行处理,上传之前,要创建一个upload目录
System.out.println("测试上传的文件");
//把文件上传到upload目录,获取上传的目录路径
String path = ServletActionContext.getServletContext().getRealPath("/upload");
//创建目标文件对象,文件名uploadFileName,格式_FileName
File destFile=new File(path,uploadFileName);
//把上传的文件,拷贝到目标文件中
FileUtils.copyFile(upload, destFile);
return SUCCESS;
}
3.配置Action
Struts2提供了一个名为fileUpload拦截器,通过配置该拦截器可以轻松地实现文件过滤。为了让fileUpload拦截器起作用,只需要在处理文件上传的Action中配置该拦截器引用即可。
配置fileUpload拦截器时可以指定如下两个参数:
参数 | 描述 |
---|---|
allowTypes | 该参数指定允许上传文件的类型,多个文件类型之间以英文逗号隔开 |
maximumSize | 该参数指定允许上传文件的大小,单位是字节 |
当文件过滤失败后,系统自动转入input逻辑视图,因此必须为Action配置名为input的逻辑视图。
<!-- 指定国际化资源文件 -->
<constant name="struts.custom.i18n.resources" value="messageResource"/>
<!--设置Struts应用的解码集-->
<constant name="struts.i18n.encoding" value="utf-8"/>
<interceptors>
<!-- 配置拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 配置fileUpload拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 配置允许上传文件的类型(此处要注意的是png图片在ie浏览器中是image/x-png类型)-->
<param name="allowedTypes">image/x-png,image/bmp,image/gif,image/jpeg,image/jpg</param>
<!-- 配置允许上传文件大小拦截器,单位是字节(2的16次幂=65536(64k))-->
<param name="maximumSize">65536</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<action name="upload" class="action.UploadAction">
<!--使用拦截器栈-->
<interceptor-ref name="myStack"/>
<result>/uploadSuccess.jsp</result>
<!--过滤失败,系统会转入input逻辑视图,这里配置其返回选择界面-->
<result name="input">/select.jsp</result>
</action>
实现文件下载
1.定义InputStream
stream结果类型(专门实现文件下载功能)
2.配置stream结果类型
将文件数据(通过ImputStream获取)直接写入响应流。
名称 | 作用 |
---|---|
contentType | 设置发送到浏览器的MIME类型 |
contentLength | 设置文件的大小 |
contentDisposition | 设置响应的HTTP头信息中的Content-Disposition参数的值 |
inputName | 指定Action中提供的inputStream类型的属性的名称 |
bufferSize | 设置读取和下载文件时的缓冲区大小 |
指定文件下载的类型(M/ME)
文件类型 | 类型设置 |
---|---|
Word | application/msword |
Excel | application/vnd.ms.excel |
PPT | application/vnd.mspowerpoint |
图片 | image/gif,image/bmp,image/jpeg |
文本文件 | text/plain |
html网页 | text/html |
任意二进制数据 | application/octet-stream |
1.JSP页面
下载中文:<a href="downLoad.action?downPath=第一章节.doc">中</a>
下载英文:<a href="downLoad.action?downPath=chapter01.doc">英</a>
2.在Struts2框架文件下载Action类中,需要提供一个返回InputStream流方法,该输入流代表了被下载文件的入口
public class DownLoadAction extends ActionSupport {
private String downPath; // 下载时的文件名
private String contentType; // 保存文件类型
private String filename; // 保存时的文件名
//省略getter/settter方法...
public void setDownPath(String downPath) {
try {
// 解决下载时候的中文文件乱码问题
downPath = new String(downPath.getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.downPath = downPath;
}
// 下载用的Action返回一个InputString实例,该方法对应Action配置里面的result的inputName参数,值为inputString
public InputStream getInputString(){
return ServletActionContext.getServletContext().getResourceAsStream(downPath);
}
public String execute(){
// 下载保存时的文件名和被下载的文件名一样
filename = downPath;
// 下载的文件路径,请在webapps目录下创建images
downPath = "images/" + downPath;
// 保存文件的类型
contentType = "application/x-msdownload";
// 对下载的文件名按照UTF-8进行编码,解决下载窗口中的中文乱码问题;其中,MyUtil是自己定义的一个类
filename = MyUtil.toUTF8String(filename);
return SUCCESS;
}
}
3.在上述的Action类中定义了一个工具类MyUtil,该类中有一个静态方法toUTF8String实现对下载的文件名按照UTF-8进行编码,解决下载窗口中中文乱码的问题:(MyUtil.java)
public class MyUtil {
// 对下载文件按照 UTF-8 进行编码
public static String toUTF8String(String str){
StringBuffer sb = new StringBuffer();
int len = str.length();
for (int i = 0; i < len; i++)
{
// 取出字符中的每个字符
char c = str.charAt(i);
// Unicode码值在0~255之间,不做处理
if(c>=0 && c <= 255){
sb.append(c);
}else {
// 转换 UTF-8 编码
byte b[];
try{
b = Character.toString(c).getBytes("UTF-8");
}catch(UnsupportedEncodingException e){
e.printStackTrace();
b = null;
}
// 转换为%HH的字符串形式
for(int j = 0;j < b.length ; j++){
int k = b[j];
if(k < 0){
k &= 255;
}
sb.append("%" + Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
}
}
4.最后,完成Action的配置,关键是要配置一个类型为stream的结果,配置时需要指定如
下四个属性:
属性 | 描述 |
---|---|
contentType | 指定被下载文件的文件类型 |
inputName | 指定被下载文件的入口输入流 |
contentDisposition | 指定下载的文件名 |
bufferSize | 指定下载文件时的缓冲大小 |
具体代码如下:(struts.xml)
<action name="downLoad" class="action.DownLoadAction">
<!--结果类型为String-->
<result type="stream">
<param name="contentType">${contentType}</param>
<!--
默认就是inputStream,它将会指示StreamResult通过
inputName属性值的getter和setter方法,如这里就是
getInputStream()来获取下载文件的内容,意味着Action
要有这个方法
-->
<param name="inputName">inputStream</param>
<!--默认为inline(在线打开),设置为attachment将会告诉浏览器下载
该文件,filename指定下载文件时的文件名,若未指定将会以浏览器
页面名作为文件名,如:以download.action作为文件名
-->
<param name="contentDisposition">attachment;filename=${filename}</param>
<!--指定下载文件的缓冲大小-->
<param name="bufferSize">4096</param>
</result>
</action>