在作B/S系统时,一般会涉及到上传文件和下载文件,在没接struts2框架以前,咱们都是使用apache下面的commons子项目的FileUpload组件来进行文件的上传,可是那样作的话,代码看起来比较繁琐,并且不灵活,在学习了struts2后,struts2为文件上传下载提供了更好的实现机制,在这里我分别就单文件上传和多文件上传的源代码进行一下讲解,这里须要导入文件下载上传的两个jar文件,一个是commons-fileupload-1.2.2.jar,另外一个是commons-io-2.0.1.jar前端
struts2单文件上传:apache
首先是一个jsp文件上传页面,这个比较简单,就是一个表单,里面有个文件上传框数组
<!--在进行文件上传时,表单提交方式必定要是post的方式,由于文件上传时二进制文件可能会很大,还有就是enctype属性,这个属性必定要写成multipart/form-data, 否则就会以二进制文本上传到服务器端--> <s:form action="uploadOne" enctype="multipart/form-data" method="POST"> <s:file name="upload" label="选择文件"/><br> <s:submit name="submit" value="上传文件"/> </s:form>
接下来是uploadOne部分代码,由于struts2对上传和下载都提供了很好的实习机制,因此在action这段咱们只须要写不多的代码就行:浏览器
public class uploadOne extends ActionSupport { //获取文件 private File upload; //获取文件的类型 private String uploadContentType; //上传文件的名称 private String uploadFileName; //获取文件上传的路径 private String path; @Override public String execute() throws Exception { byte[] bytes=new byte[1024]; //读取文件 FileInputStream fis=new FileInputStream(getUpload()); //写入文件,并设置保存目录的路径 FileOutputStream fos=new FileOutputStream(getPath()+"\\"+getUploadFileName()); int length=fis.read(bytes); while (length>0){ fos.write(bytes,0,length); length=fis.read(bytes); } fos.close(); fos.flush(); fis.close(); return SUCCESS; } //获取上传文件的保存路径 //经过读取存放目录得到保存路径 public String getPath() { return ServletActionContext.getServletContext().getRealPath(path); } public void setPath(String path) { this.path = path; } 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; } }
首先咱们要清楚一点,这里的upload并非真正指代jsp上传过来的文件,当文件上传过来时,struts2首先会寻找struts.multipart.saveDir(这个是在default.properties里面有)这个name所指定的存放位置,咱们能够新建一个struts.properties属性文件来指定这个临时文件存放位置,若是没有指定,那么文件会存放在tomcat的apache-tomcat-7.0.29\work\Catalina\localhost\目录下,而后咱们能够指定文件上传后的存放位置,经过输出流将其写到流里面就好了,这时咱们就能够在文件夹里看到咱们上传的文件了。tomcat
struts.xml配置服务器
<action name="uploadOne" class="cn.happy.action.uploadOne"> <!--经过param参数设置保存目录的路径--> <param name="path">/upload</param> <result name="success">oneUpload/two.jsp</result> </action>
文件上传后咱们还须要将其下载下来,其实struts2的文件下载原理很简单,就是定义一个输入流,而后将文件写到输入流里面就行,关键配置仍是在struts.xml这个配置文件里配置:app
FileDownloadAction代码以下:框架
//读取下载文件的目录 private String inputPath; //下载文件的文件名 private String fileName; //读取下载文件的输入流 private InputStream inputStream; //下载文件的类型 private String contntType; //建立InputStream输入流 public InputStream getInputStream() throws FileNotFoundException { String path= ServletActionContext.getServletContext().getRealPath(inputPath); return new BufferedInputStream(new FileInputStream(path+"\\"+fileName)); } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } 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; }
struts.xml配置jsp
<action name="first" class="cn.happy.action.FileAction"> <param name="inputPath">/upload</param> <result name="success" type="stream"> <!-- 指定下载文件的内容类型,text/plain是默认类型 --> <param name="contntType">application/octet-stream</param> <!-- inputName默认值是inputStream,若是action中用于读取 下载文件内容的属性名是inputStream,那么能够省略这个参数 --> <param name="inputName">inputStream</param> <!--动态获取文件名,从Action中的取得filename--> <param name="contentDisposition"> attachment;filename="${fileName}" </param> <param name="bufferSize">2048</param> </result>
struts.xml配置文件有几个地方咱们要注意,首先是result的类型,之前咱们定义一个action,result那里咱们基本上都不写type属性,由于其默认是请求转发(dispatcher)的方式,除了这个属性通常还有redirect(重定向)等这些值,在这里由于咱们用的是文件下载,因此type必定要定义成stream类型,告诉action这是文件下载的result,result元素里面通常还有param子元素,这个是用来设定文件下载时的参数,inputName这个属性就是获得action中的文件输入流,名字必定要和action中的输入流属性名字相同,而后就是contentDisposition属性,这个属性通常用来指定咱们但愿经过怎么样的方式来处理下载的文件,若是值是attachment,则会弹出一个下载框,让用户选择是否下载,若是不设定这个值,那么浏览器会首先查看本身可否打开下载的文件,若是能,就会直接打开所下载的文件,(这固然不是咱们所须要的),另一个值就是filename这个就是文件在下载时所提示的文件下载名字。ide
contentDispoistion参数由两部分组成,前面的部分表示处理文件的形式,如attachement表示在下载是弹出对话框,提示用户保存或者直接打开该文件;然后一部分表示下载文件的文件名称。两部分之间以;进行分隔。
在配置完这些信息后,咱们就能过实现文件的下载功能了。
下载文件jsp页面
<a href="first?fileName=ehcache.xml">点击此处下载文件</a>
struts2多文件上传:
其实多文件上传和单文件上传原理同样,单文件上传过去的是单一的File,多文件上传过去的就是一个List<File>集合或者是一个File[]数组,首先咱们来看一下前端jsp部分的代码,
<s:form action="more" enctype="multipart/form-data" method="POST"> <s:file name="upload" label="选择文件"/><br> <s:file name="upload" label="选择文件"/><br> <s:submit name="submit" value="上传文件"/> </s:form>
file的名字必须都命名成upload才行,而后处理多文件上传的action代码以下:
public class MoreUploadAction extends ActionSupport{ //获取文件 private List<File> upload; //获取文件的类型 private List<String> uploadContentType; //上传文件的名称 private List<String> uploadFileName; //获取文件上传的路径 private String path; @Override public String execute() throws Exception { byte[] bytes=new byte[1024]; int index=0; for (File item:upload) { FileInputStream inputStream=new FileInputStream(item); FileOutputStream output=new FileOutputStream(getPath()+"\\"+getUploadFileName().get(index++)); int length=inputStream.read(bytes); while (length>0){ output.write(bytes,0,length); length=inputStream.read(bytes); } output.flush(); output.close(); inputStream.close(); } return SUCCESS; } //获取上传文件的保存路径 //经过读取存放目录得到保存路径 public String getPath() { return ServletActionContext.getServletContext().getRealPath(path); } public void setPath(String path) { this.path = path; } public List<File> getUpload() { return upload; } public void setUpload(List<File> upload) { this.upload = upload; } public List<String> getUploadContentType() { return uploadContentType; } public void setUploadContentType(List<String> uploadContentType) { this.uploadContentType = uploadContentType; } public List<String> getUploadFileName() { return uploadFileName; } public void setUploadFileName(List<String> uploadFileName) { this.uploadFileName = uploadFileName; }
struts.xml配置
<!--多文件上传--> <action name="more" class="cn.happy.action.MoreUploadAction"> <!--经过param参数设置保存目录的路径--> <param name="path">/upload</param> <result name="success">moreUpload/two.jsp</result> </action>
这样一样将其写到一个输出流里面,这样咱们就能够在文件夹里看到上传的多个文件了
接下来的文件下载就和刚才的文件下载如出一辙,struts.xml也是同样的,这里就再也不重复了
总结:总的来讲,struts2提供的文件上传下载机制简化了咱们不少代码,咱们能够在之后的项目中使用该机制,一样咱们也可使用FileUpload组件来进行文件的上传,这个都是因我的爱好决定!