Struts2文件上传和文件下载
一.单个文件上传
文件上传需要两个jar包:
首先制作一个简单的页面,用于实现文件上传
<h1>单个文件上传</h1> <s:form action="upload.action" enctype="multipart/form-data" method="post" namespace="/"> <s:textfield name="title" lable="标题"></s:textfield> <s:file name="upload" lable="选择文件"></s:file> <s:submit value="上传文件"></s:submit> </s:form>
开发实现文件上传的Action
package cn.action; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport{ //封装上传文件属性 private File upload; //封装上传文件的类型 private String uploadContentType; //封装上传文件名称 private String uploadFileName; //封装文件上传的路径 private String savePath; public String execute(){ byte[] buffer=new byte[1024]; try { FileInputStream fis=new FileInputStream(getUpload()); FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName()); int length=fis.read(buffer); while(length>0){ fos.write(buffer, 0, length); length=fis.read(buffer); } fos.flush(); fos.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("========================"); return SUCCESS; } public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadContentType() { return uploadContentType; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } public String getSavePath() { return ServletActionContext.getServletContext().getRealPath(savePath); } public void setSavePath(String savePath) { this.savePath = savePath; } }
在Action中使用了三个属性封装文件信息
File类型的XXX属性,与表单的File控件的name属性一样,用于封装File控件对应的文件内容
String类型的xxxFileName属性,该属性名称由前面的File类型属性和FileName组合,是固定的语法,是封装File控件对应文件的文件名
String类型的XXXContentType属性,同样由xxx属性和ContentType组合而成,是固定语法,封装File控件对应文件的文件类型
配置Action
<!-- 单个文件上传 --> <action name="upload" class="cn.action.UploadAction"> <!-- 通过param参数设置保存目录的路径 --> <param name="savePath">/upload</param> <result name="success">success.jsp</result> </action>
效果图:
二.多个文件上传
只需在上传Action中将原本处理单个文件的操作改成对集合操作即可。
其他的都跟单个上传的一样
页面
<!-- 多个文件上传 --> <action name="someupload" class="cn.action.SomeUploadAction"> <!-- 通过param参数设置保存目录的路径 --> <param name="savePath">/upload</param> <result name="success">success.jsp</result> </action>
开发实现文件上传的Action
package cn.action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class SomeUploadAction extends ActionSupport { //封装上传文件属性 private File[] upload; //封装上传文件的类型 private String[] uploadContentType; //封装上传文件名称 private String[] uploadFileName; //封装文件上传的路径 private String savePath; public String execute() throws Exception{ byte[] buffer=new byte[1024]; for (int i = 0; i < upload.length; i++) { FileInputStream fis=new FileInputStream(getUpload()[i]); FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName()[i]); int length=fis.read(buffer); while(length>0){ fos.write(buffer, 0, length); length=fis.read(buffer); } fos.flush(); fos.close(); fis.close(); } return SUCCESS; } public File[] getUpload() { return upload; } public void setUpload(File[] upload) { this.upload = upload; } public String[] getUploadContentType() { return uploadContentType; } public void setUploadContentType(String[] uploadContentType) { this.uploadContentType = uploadContentType; } public String[] getUploadFileName() { return uploadFileName; } public void setUploadFileName(String[] uploadFileName) { this.uploadFileName = uploadFileName; } public String getSavePath() { return ServletActionContext.getServletContext().getRealPath(savePath); } public void setSavePath(String savePath) { this.savePath = savePath; } }
配置Action
<!-- 多个文件上传 --> <action name="someupload" class="cn.action.SomeUploadAction"> <!-- 通过param参数设置保存目录的路径 --> <param name="savePath">/upload</param> <result name="success">success.jsp</result> </action>
效果:
三.文件下载
文件下载需要InputStream,首先在文件下载Action中提供一个获得InputStream的方法,通过输入流可以获取希望下载的文件内容
package cn.action; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class FileDownAction extends ActionSupport { //读取下载文件的目录 private String inputPath; //下载文件的文件名 private String fileName; //读取下载文件的输入流 private InputStream inputStream; //下载文件的类型 private String conetntType; public String execute(){ return SUCCESS; } public String getInputPath() { return inputPath; } public void setInputPath(String inputPath) { this.inputPath = inputPath; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } //创建InputStream输入流 public InputStream getInputStream() throws Exception { String path=ServletActionContext.getServletContext().getRealPath(inputPath); BufferedInputStream stream = new BufferedInputStream(new FileInputStream(path+"\\"+fileName)); return stream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public String getConetntType() { return conetntType; } public void setConetntType(String conetntType) { this.conetntType = conetntType; } }
通过Context得到下载文件的实际路径,构建一个InputStream输入流实现文件的下载读取。
在配置文件中,同样对Action进行配置,并对stream结果类型的参数进行设置。
<!-- download指定的Action --> <action name="download" class="cn.action.FileDownAction"> <param name="inputPath">/upload</param> <result name="success" type="stream"> <param name="contentType">application/octet-stream</param> <param name="inputName">inputStream</param> <param name="contentDisposition"> attachment;filename="${fileName}" </param> <param name="bufferSize">4096</param> </result> </action>
ContentType参数决定了下载文件的类型,不同的文件类型对应的参数值也是不同的。
通常情况下,ContentType参数直接设置为application/octet-stream即可。
contentDisposition参数由两部分组成,前面的部分表示处理文件的形式,如attachement表示在下载时弹出对话框,提出用户保存或直接打开该文件;而后一部分表示下载文件的文件名称。两部分之间用“;”进行分隔。
然后开发一个简单的下载页面,在页面中设置一个超链接,通过超链接请求下载Action
<h1>文件下载</h1> <s:a href="download.action?fileName=2.jpg">点击此处下载文件</s:a>
效果: