Struts2实现文件的上传与下载
Posted Java与大数据学习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2实现文件的上传与下载相关的知识,希望对你有一定的参考价值。
上传
第一步:静态展示页面
<h1>文件上传</h1>
<form action="/StrutsDay1/test/upload" method="post" enctype="multipart/form-data">
<input type="file" name="pic" ><br />
<input type="submit" value="上传">
</form>
注意:
method="post",只有post支持二进制的传输方式,
添加enctype属性,并且设置值为“multipart/form-data”,将表单数据以二进制流的形式发送到服务器
input type的类型为“file”
第二步:Action接收表单提交的数据,获取到提交的文件,并将获取的文件拷贝到服务器项目所在的目录下
public class FIleUploadAction {
private File pic;
private String picFileName;//自动获取文件名
public String getPicFileName() {
return picFileName;
}
public void setPicFileName(String picFileName) {
this.picFileName = picFileName;
}
public File getPic() {
return pic;
}
public void setPic(File pic) {
this.pic = pic;
}
public String upload() throws IOException{
//获得真实路径
ServletContext sc = ServletActionContext.getServletContext();
String realPath = sc.getRealPath("/picture");
//输出文件(将文件拷贝到服务器中项目的目录)
/*
*其实就是一个文件拷贝的过程,https://gitee.com/sixiaojie/codes/3ouditmhkznlyjv0efcx731
*这个链接介绍了通过IO实现的六种拷贝方式,我在这里选择了其中的一种
*/
FileInputStream fis = new FileInputStream(pic);
FileOutputStream fos = new FileOutputStream(realPath+"/"+picFileName);
FileChannel channel1 = fis.getChannel();
FileChannel channel2 = fos.getChannel();
channel1.transferTo(0, channel1.size(), channel2);
channel1.close();
channel2.close();
return "upload";
}
}
第三步:在struts.xml中注册Action
<?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="test" extends="struts-default" namespace="/test">
<!-- 文件上传 -->
<action name="upload" class="demo1.FIleUploadAction" method="upload">
<result name="upload" type="redirect">/index.jsp</result>
</action>
</package>
</struts>
现在其实就可以在页面选择文件,然后保存到服务器了,但是,目前的程序是存在很多问题的,还有很多需要优化的地方,下面开始优化!
优化文件上传程序
上传的文件大小问题,Struts2默认接收上传文件的最大限度为2M;
文件上传大小的上限是可以修改的,在Struts.xml文件中配置常量,标签为:
默认的maxSize为2097152,是以字节为单位,也就是2M
<constant name="struts.multipart.maxSize" value="100000000"></constant>文件名问题,用户上传文件的文件名可能在服务器端冲突,为了解决这个问题,可以使用UUID生成唯一的名字作为文件名,代码:
UUID.randomUUID().toString();
文件名设计为 UUID.后缀,后缀名可以通过接收到的picFileName问价名获取,获取方式:
String name = UUID.randomUUID().toString()+picFileName.substring(picFileName.lastIndexOf('.'));
文件保存路径问题,保存文件的目录写死在代码中,耦合,不便于维护,解决办法:保存目录名转移到struts.xml配置文件中,在原来基础上使用到一个param标签
<?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="test" extends="struts-default" namespace="/test">
<!-- 文件上传 -->
<action name="upload" class="demo1.FIleUploadAction" method="upload">
<param name="filePath">/picture</param>
<result name="upload" type="redirect">/index.jsp</result>
</action>
</package>
</struts>当浏览器请求name为upload的Action的时候,会自动将param中的值以请求参数的方式发送给Action,这样就可以在Action中接收到“filePath”的值为/picture,同样使用属性名的方式接收
文件拷贝的代码简化,在搭建Struts2开发环境的时候,导入了一些jar包,其中有一个commons-io的jar包,这个jar包中封装拷贝文件的方法:
FileUtils.copyFile(Pic, new File(picturePath));
第一个参数为被拷贝的文件对象,第二个参数为拷贝之后的文件对象,picturePath为目标的文件的路径
那么优化之后的Action的文件为
public class FIleUploadAction {
private File pic;
private String picFileName;
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getPicFileName() {
return picFileName;
}
public void setPicFileName(String picFileName) {
this.picFileName = picFileName;
}
public File getPic() {
return pic;
}
public void setPic(File pic) {
this.pic = pic;
}
public String upload() throws IOException{
//获得真实路径
ServletContext sc = ServletActionContext.getServletContext();
String realPath = sc.getRealPath(filePath);
//文件名
String fileName = UUID.randomUUID().toString()+picFileName.substring(picFileName.lastIndexOf('.'));
//拷贝输出文件
FileUtils.copyFile(pic, new File(realPath+"/"+fileName));
return "upload";
}
}
下载
当浏览器访问action的时候,action将文件发送到浏览器,供浏览器下载
文件下载相对较为简单,下面为action中的一个方法:
public void download() throws Exception {
//以这个文件为例,为了演示所以直接给出了文件名
String fileName = "cc21afb1-88f0-45e4-928e-bb0046aac045.jpg";
//1. 设置下载信息以文件保存(filename指定文件名)
//URLEncoder.encode(fileName, "UTF-8"),设置编码格式,否则中文不会显示
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
// 1. 读入服务器端文件输入流
// 路径
String realPath = ServletActionContext.getServletContext().getRealPath(
"/upload");
String filePath = realPath + "/" + fileName;
//2. 将服务器端要下载文件-----(拷贝到)----》响应输出流
File srcFile = new File(filePath);
ServletOutputStream os = response.getOutputStream();
// 将srcFile文件读入,写出到os对应输出流中。
// 3. 边读边写。
FileUtils.copyFile(srcFile, os);
}
只要浏览器访问该浏览器,浏览器就会将服务器端的文件通过响应输出流发送到浏览器,浏览器就会弹出一个下载框,提示下载该文件。
以上是关于Struts2实现文件的上传与下载的主要内容,如果未能解决你的问题,请参考以下文章