您的位置:首页 > 编程语言 > Java开发

Struts2实现文件的上传与下载

2015-08-09 22:11 507 查看
感谢:Struts2多个文件上传的分析及源代码说明

一 介绍

1.新建项目,并导入相应的包





2. Struts2文件上传并未提供自己的请求解析器,也就是说,struts2不会自己去处理multipart/form-data的请求,它需要调用其他的请求解析器,将http请求中的表单域解析出来。但struts2在原有的上传解析器继承上做了进一步封装,更进一步简化了文件上传。

3. Struts2默认使用的是Jakarta和Connon-FileUpload的文件上传框架,因此,如果需要使用struts2的文件上传功能,则需要在Web应用导入上面我所说的几个包
二.实例
1.表单enctype属性

表单的enctype属性指定的是表单数据的编码方式,该属性呢有3个值
(1) application/x-www-form-urlencoded,这是默认的编码方式,它只能处理表单域里的value属性,采用这种编码方式的表单会将表单域的值处理成URL编码方式。
(2)multipart/form-data,采用这种编码方式会以二进制流的方式来处理表单数据 ,这种编码方式会把文件域指定文件的内容也封装到请求参数里。
(3)text/plain,这种编码方式当表单的action属性为mailto:URL的形式是比较方便,这种方式主要适用于直接通过表单发送邮件的方式。
2.html代码:

<span style="font-size:14px;"><body>
<form method="POST" enctype="multipart/form-data" action="upload.html">
File to upload: <input type="file" name="file"><br /> <br />
Notes about the file: <input type="text" name="note"><br /> <br />
<input type="submit" value="Press"> to upload the file!
</form><br><br>

<form method="POST" enctype="multipart/form-data" action="uploadList.html">
File to upload: <input type="file" name="fileList"><br /> <br />
File to upload: <input type="file" name="fileList"><br /> <br />
File to upload: <input type="file" name="fileList"><br /> <br />
Notes about the file: <input type="text" name="notes"><br /> <br />
<input type="submit" value="Press"> to upload the file!
</form><br><br>

<a href="listAllFile.html">List all files</a>
</body></span>
struts.properties配置

<span style="font-size:14px;">#指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法
struts.i18n.encoding=UTF-8
#开发者模式,这样可以打印出更详细的错误信息
struts.devMode=true
#设置是否每次请求,都重新加载资源文件,默认值为false.
struts.i18n.reload=true
#当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开
struts.configuration.xml.reload=true
#设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭
struts.serve.static.browserCache=false
#指定Struts 2文件上传中整个请求内容允许的最大字节数,100M
struts.multipart.maxSize=104857600
#设置url请求后缀
struts.action.extension=html</span>
struts.xml

<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
<package name="default" namespace="/" extends="struts-default">

<action name="upload" class="com.lxz.UploadAndDownloadAction"
method="upload">
<result name="success">/WEB-INF/results.jsp</result>

<interceptor-ref name="fileUpload">
<!-- 拦截器允许的上传到当前action中的文件最大长度(以byte为单位) -->
<!-- properties中的struts.multipart.maxSize和action拦截器的maximumSize属性分工不同 -->
<!-- struts.multipart.maxSize掌控整个项目所上传文件的最大的Size,超过了这个size,后台报错,默认2M -->
<!-- action拦截器的maximumSize属性必须小于struts.multipart.maxSize的值 -->
<!-- <param name="maximumSize">2*1024*1024</param> -->
<!-- 拦截器允许的可以传到action中的contentType,如果没有指定就是允许任何上传类型 -->
<param name="allowedTypes">
text/plain,application/msword,image/jpeg
</param>
</interceptor-ref>
<!-- 自定义了拦截器后必手动定义默认的拦截器,否则默认的拦截器不会被执行 -->
<interceptor-ref name="defaultStack" />
</action>

<action name="uploadList" class="com.lxz.UploadAndDownloadAction"
method="uploadList">
<result name="success">/WEB-INF/results.jsp</result>

<interceptor-ref name="fileUpload">
<!-- <param name="maximumSize">2*1024*1024</param> -->
<param name="allowedTypes">
text/plain,application/msword,image/jpeg
</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
</action>
<action name="download" class="com.lxz.UploadAndDownloadAction"
method="download">
<result type="stream" name="success">
<!-- 文件类型 ,application/octet-stream 表示无限制 -->
<param name="contentType">application/octet-stream</param>
<!-- 数据流对象名,由Action中的getInputStream方法获得 -->
<param name="inputName">inputStream</param>
<!-- 指定下载的文件名和显示方式 ,但注意中文名的乱码问题,解决办法是:进行编码处理 -->
<!-- contentDisposition是文件下载的处理方式,包括内联(inline)和附件(attachment) -->
<!-- 默认是inline,使用附件时这样配置:attachment;filename="文件名" -->
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<!-- 指定下载文件的缓存大小 -->
<param name="bufferSize">4096</param>
</result>
<result type="dispatcher" name="error">/WEB-INF/results.jsp</result>
</action>

<action name="listAllFile" class="com.lxz.UploadAndDownloadAction"
method="listAllFile">
<result>/WEB-INF/results.jsp</result>
</action>

</package>

</struts>
</span>
action

<span style="font-size:14px;">package com.lxz;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class UploadAndDownloadAction extends ActionSupport {
private static final long serialVersionUID = 1L;

private InputStream inputStream;
private String fileName;

private File file; // file并不是指前端jsp上传过来的文件本身,而是文件上传过来存放在临时文件夹下面的文件
private String note;
private String fileFileName; // 上传文件的名称,file,fileFileName,fileContentType对应
private String fileContentType; // 上传文件的类型(提交过来的file的MIME类型)

private List<File> fileList;
private String notes;
private List<String> fileListFileName;
private List<String> fileListContentType;

/*private File[] fileList;
private String[] fileListFileName;
private Str
b55c
ing[] fileListContentType;*/
/**
* 上传单个文件
*/
public String upload() throws Exception {
// 把上传的文件放到指定的路径下
String path = ServletActionContext.getServletContext().getRealPath(
"/WEB-INF/upload");

System.out.println("path = " + path);
System.out.println("fileFileName = " + fileFileName);
System.out.println("fileContentType = " + fileContentType);
System.out.println("note = " + note);

File saveFile = new File(path);
// 如果指定的路径没有就创建
if (!saveFile.exists() && !saveFile.isDirectory()) {
saveFile.mkdir();
}
if (file != null) {
// 输出流
OutputStream os = new FileOutputStream(new File(path , fileFileName));
// 输入流
InputStream is = new FileInputStream(file);

System.out.println("path = " + path);
System.out.println("file.getName() = " + file.getName());
System.out.println("file.getPath = " + file.getPath());

byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
is.close();
os.close();
ActionContext.getContext().put("message", "上传成功");
}
return SUCCESS;
}

/**
* 上传多个文件,可采用集合和数组的方法
*/
public String uploadList() throws Exception {
// 把上传的文件放到指定的路径下
String path = ServletActionContext.getServletContext().getRealPath(
"/WEB-INF/uploadList");

File saveFile = new File(path);
// 如果指定的路径没有就创建
if (!saveFile.exists() && !saveFile.isDirectory()) {
saveFile.mkdir();
}
// 把得到的文件的集合通过循环的方式读取并放在指定的路径下
for(int i=0;i<fileList.size();i++){
if(fileList.get(i) != null){
// 输出流
OutputStream os = new FileOutputStream(new File(path , fileListFileName.get(i)));
// 输入流
InputStream is = new FileInputStream(fileList.get(i));

System.out.println("path = " + path);
System.out.println("fileList.get(i).getName() = " + fileList.get(i).getName());
System.out.println("fileList.get(i).getPath = " + fileList.get(i).getPath());

byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
is.close();
os.close();
ActionContext.getContext().put("message", "上传成功");
}
}
return SUCCESS;
}

/**
* 下载文件
*/
public String download() throws Exception {
// 解码,绝对路径
String realName = URLDecoder.decode(fileName, "UTF-8");
// 获取数据流
inputStream = new FileInputStream(realName);
// 获取文件名
fileName = new String(
(realName.substring(realName.lastIndexOf("/") + 1))
.getBytes("UTF-8"),
"ISO-8859-1");
return SUCCESS;
}

/**
* 列出所有文件
*/
public String listAllFile() throws Exception {
// 文件目录
String filePath = "d:/temp";
File file = new File(filePath);

// 存储要下载的文件
Map<String, String> fileMap = new HashMap<String, String>();

// 如果目录存在,并且目录是一个文件夹
if (file.exists() && file.isDirectory()) {
// 获取所有文件
this.getFiles(file, fileMap);
ActionContext context = ActionContext.getContext();
// 向request里放attribute
context.put("fileMap", fileMap);
// 向session里放attribute
// context.getSession().put("fileMap", fileMap);
} else {
file.mkdir();
}
return SUCCESS;
}

public void getFiles(File file, Map<String, String> fileMap)
throws Exception {
// 目录为文件夹
if (file.isDirectory()) {
File[] files = file.listFiles();
// 遍历数组
for (File f : files) {
// 递归
getFiles(f, fileMap);
}
} else {// 文件
// file.getAbsolutePath()获取文件绝对路径,唯一值,如:d:\temp\aaa.txt,需要转为d:/temp/aaa.txt
// file.getName()获得文件名,如:aaa.txt
fileMap.put(file.getAbsolutePath().replace("\\", "/"),
file.getName());
}
}

<span style="white-space:pre">	</span>//set,get方法省略
}
</span>


通过以上的Action我们可以看出Action还包括了两个属性,fileFileName,fileContentType, 这两个属性分别用来封装上传我文件的文件名,上传文件的文件类型,Action类直接通过File类型属性直接封装了上传文件的内容,但这个File属性无法获取上传文件的文件名和文件类型,所以struts2直接将包含的上传文件名和文件类型的信息封装到fileFileName,fileContentType属性中,可以认为:如果表单中包含一个name属性为xxx的文件域,则对应的Action需要使用3个属性来封装该文件域的信息:

(1)   类型为File的xxx属性封装了该文件域对应的文件内容

(2)   类型为String的xxxFileName属性封装了该案文件域对应的文件的文件类型

(3)   类型为String的xxxContentType属性封装了该文件域对应的文件的类型
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息