Java程序员从笨鸟到菜鸟之(七十一)细谈struts2(十三)struts2实现文件上传和下载详解
2012-06-08 14:19
1201 查看
文件上传和文件下载是我们在web应用程序中常用的两个功能,在java中,实现这两种功能的方式也有很多种,其中struts2就给我们提供了一种算是比较简单的方式吧,下面我们就一起来看一下,首先我们来看文件上传:
文件上传
文件上传我们首先应该注意的是在上传页面的表单,这个表单也是有讲究的,由于我们提交表单的数据中有文件上传,所以这个表单的所使用的编码类型就不能是原来的了,在这里我们应该使用的编码方式是multipart/form-data,并且数据提交方式要用post方式,下面我们具体来看一下:
Form.jsp:
OK,看完表单以后我们就要来看一下action里面是怎么来接收这些数据的,其实也很简单,直接在action中定义三个变量,这三个变量分别是文件、文件名,还有文件类型,如下:
这三个变量的名字是有讲究的,不是随便命名就OK了,其中file这个变量名要和表单中文件的name要相同,fileFileName这个也是固定的,起名格式就是name+FileName,同样fileContentType也是如此,命名规则是name+ContentType,只有你按照命名规则来定义变量,struts2才能把文件上传相关信息收集起来。Ok,看完了变量设置,下面我们来看一下怎么struts2是怎么把文件上传到我们指定的位置的。那我们就先上代码,让代码帮我们来理解:
我们可以看到,就是简单的几行代码,其实并不难,他主要就是利用了IO流来实现的文件上传。单文件上传实现以后,多文件上传实现起来就不难了。
多文件上传
与单文件上传相似,Struts 2实现多文件上传也很简单。你可以使用多个<s:file />绑定Action的数组或列表。
如果你希望绑定到数组,Action的代码应类似:
如果你想绑定到列表,则应类似:
收集好数据之后,文件上传步骤就和上面单文件的一样了。在这就不重复了。好了,文件上传占时先说到这,下一步我们来看一下文件下载。
文件下载
Struts 2中对文件下载做了直接的支持,相比起自己辛辛苦苦的设置种种HTTP头来说,现在实现文件下载无疑要简便的多。说起文件下载,最直接的方式恐怕是直接写一个超链接,让地址等于被下载的文件,例如:<a href=”file1.zip”> 下载file1.zip</a> ,之后用户在浏览器里面点击这个链接,就可以进行下载了。但是它有一些缺陷,例如如果地址是一个图片,那么浏览器会直接打开它,而不是显示保存文件的对话框。再比如如果文件名是中文的,它会显示一堆URL编码过的文件名例如%3457...。而假设你企图这样下载文件:http://localhost:8080/struts2/download/java程序员由笨鸟到菜鸟.doc ,Tomcat会告诉你一个文件找不到的404错误:HTTP Status 404 - /struts2hello/download/ϵͳ˵Ã÷.doc 。 所以在此我们就要用到struts 给我们提供的文件下载了。下面我们就一起来看一下struts2给我们提供的文件下载:
其实struts2提供给我们的文件下载已经非常简单化了,编写一个普通的Action就可以了,只需要提供一个返回InputStream流的方法,该输入流代表了被下载文件的入口,这个方法用来给被下载的数据提供输入流,意思是从这个流读出来,再写到浏览器那边供下载。这个方法需要由开发人员自己来编写,只需要返回值为InputStream即可 。首先我们来看一下jsp页面:
页面很简单,就一下下载的链接,然后这个链接链接到我们的action中,下一步我们来看一下我们的action的编写:
下面我们在来看一下struts.xml的配置:
这个action特殊的地方在于result的类型是一个流(stream ),配置stream类型的结果时,因为无需指定实际的显示的物理资源,所以无需指定location 属性,只需要指定inputName 属性,该属性指向被下载文件的来源,对应着Action类中的某个属性,类型为InputStream。下面则列出了和下载有关的一些参数列表:
参数说明
contentType
内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片
inputName
下载文件的来源流,对应着action类中某个类型为Inputstream的属性名,例如取值为inputStream 的属性需要编写getInputStream()方法
contentDisposition
文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。取值为:attachment;filename="struts2.txt" ,表示文件下载的时候保存的名字应为struts2.txt 。如果直接写filename="struts2.txt" ,那么默认情况是代表inline ,浏览器会尝试自动打开它,等价于这样的写法:inline; filename="struts2.txt"
bufferSize
下载缓冲区的大小
在这里面,contentType 属性和contentDisposition 分别对应着HTTP响应中的头Content-Type 和Content-disposition 头
当然,在很多的时候我们一般都不是把文件名写死在xml配置当中的,我们一般会在action中定义一个变量downfilename,储存这个文件名,然后再xml配置:
我们经常在中文下载中,出现文件名乱码的问题,这个问题是很多人都常见的,具体的很好的解决方法也没有,但我以前用的时候尝试着给他重新编码,这样可以解决大部分时候的中文下载乱码问题,但有时候也不行的。具体重新编码就是:
好了,struts2文件上传和下载就简单介绍到这,文章中有什么不对或者错误的地方,欢迎大家指正。
文件上传
文件上传我们首先应该注意的是在上传页面的表单,这个表单也是有讲究的,由于我们提交表单的数据中有文件上传,所以这个表单的所使用的编码类型就不能是原来的了,在这里我们应该使用的编码方式是multipart/form-data,并且数据提交方式要用post方式,下面我们具体来看一下:
Form.jsp:
<form action="StudentAction!addStu" target="mainFrame" onsubmit="javascript:window.close()" method="post" enctype="multipart/form-data"> <table class="ta" width="200px"> <td>姓名</td> <td><input type="text" name="stu.name" value="${request.stu_info.name }"/></td> </tr> <tr bgColor="#6fdd0"> <td>上传头像</td> <td><input type="file" name="file" /> </td> </tr> <tr bgColor="#6fdd0"> <td colspan="2"><input type="submit" value="提交" class="buStyle"/> <input type="reset" value="重置" class="buStyle"/></td> </tr> </table> </form>
OK,看完表单以后我们就要来看一下action里面是怎么来接收这些数据的,其实也很简单,直接在action中定义三个变量,这三个变量分别是文件、文件名,还有文件类型,如下:
private File file; private String fileFileName; private String fileContentType;
这三个变量的名字是有讲究的,不是随便命名就OK了,其中file这个变量名要和表单中文件的name要相同,fileFileName这个也是固定的,起名格式就是name+FileName,同样fileContentType也是如此,命名规则是name+ContentType,只有你按照命名规则来定义变量,struts2才能把文件上传相关信息收集起来。Ok,看完了变量设置,下面我们来看一下怎么struts2是怎么把文件上传到我们指定的位置的。那我们就先上代码,让代码帮我们来理解:
String root = ServletActionContext.getRequest().getRealPath("/upload"); try{ InputStream is = new FileInputStream(file); // 创建一个文件,路径为root,文件名叫fileFileName //自定义文件名 fileFileName="111"+fileFileName.substring(fileFileName.lastIndexOf(".")); File destFile = new File(root, fileFileName); // 开始上传 OutputStream os = new FileOutputStream(destFile); byte[] buffer = new byte[50000]; int length = 0; // enctype="multipart/form-data" while (-1 != (length = is.read(buffer))) { os.write(buffer, 0, length); }
我们可以看到,就是简单的几行代码,其实并不难,他主要就是利用了IO流来实现的文件上传。单文件上传实现以后,多文件上传实现起来就不难了。
多文件上传
与单文件上传相似,Struts 2实现多文件上传也很简单。你可以使用多个<s:file />绑定Action的数组或列表。
< s:form action ="doMultipleUploadUsingList" method ="POST" enctype ="multipart/form-data" > < s:file label ="File (1)" name ="upload" /> < s:file label ="File (2)" name ="upload" /> < s:file label ="FIle (3)" name ="upload" /> < s:submit /> </ s:form >
如果你希望绑定到数组,Action的代码应类似:
private File[] uploads; private String[] uploadFileNames; private String[] uploadContentTypes; public File[] getUpload() { return this .uploads; } public void setUpload(File[] upload) { this .uploads = upload; } public String[] getUploadFileName() { return this .uploadFileNames; } public void setUploadFileName(String[] uploadFileName) { this .uploadFileNames = uploadFileName; } public String[] getUploadContentType() { return this .uploadContentTypes; } public void setUploadContentType(String[] uploadContentType) { this .uploadContentTypes = uploadContentType; }
如果你想绑定到列表,则应类似:
private List < File > uploads = new ArrayList < File > (); private List < String > uploadFileNames = new ArrayList < String > (); private List < String > uploadContentTypes = new ArrayList < String > (); public List < File > getUpload() { return this .uploads; } public void setUpload(List < File > uploads) { this .uploads = uploads; } public List < String > getUploadFileName() { return this .uploadFileNames; } public void setUploadFileName(List < String > uploadFileNames) { this .uploadFileNames = uploadFileNames; } public List < String > getUploadContentType() { return this .uploadContentTypes; } public void setUploadContentType(List < String > contentTypes) { this .uploadContentTypes = contentTypes; }
收集好数据之后,文件上传步骤就和上面单文件的一样了。在这就不重复了。好了,文件上传占时先说到这,下一步我们来看一下文件下载。
文件下载
Struts 2中对文件下载做了直接的支持,相比起自己辛辛苦苦的设置种种HTTP头来说,现在实现文件下载无疑要简便的多。说起文件下载,最直接的方式恐怕是直接写一个超链接,让地址等于被下载的文件,例如:<a href=”file1.zip”> 下载file1.zip</a> ,之后用户在浏览器里面点击这个链接,就可以进行下载了。但是它有一些缺陷,例如如果地址是一个图片,那么浏览器会直接打开它,而不是显示保存文件的对话框。再比如如果文件名是中文的,它会显示一堆URL编码过的文件名例如%3457...。而假设你企图这样下载文件:http://localhost:8080/struts2/download/java程序员由笨鸟到菜鸟.doc ,Tomcat会告诉你一个文件找不到的404错误:HTTP Status 404 - /struts2hello/download/ϵͳ˵Ã÷.doc 。 所以在此我们就要用到struts 给我们提供的文件下载了。下面我们就一起来看一下struts2给我们提供的文件下载:
其实struts2提供给我们的文件下载已经非常简单化了,编写一个普通的Action就可以了,只需要提供一个返回InputStream流的方法,该输入流代表了被下载文件的入口,这个方法用来给被下载的数据提供输入流,意思是从这个流读出来,再写到浏览器那边供下载。这个方法需要由开发人员自己来编写,只需要返回值为InputStream即可 。首先我们来看一下jsp页面:
<body> <h1>文件下载</h1> <!-- 下载链接 --> <s:a action="down.action">download</s:a> </body>
页面很简单,就一下下载的链接,然后这个链接链接到我们的action中,下一步我们来看一下我们的action的编写:
public class DownAction extends ActionSupport { private static final long serialVersionUID = 1L; private String inputPath; public String getInputPath() { return inputPath; } public void setInputPath(String inputPath) { this.inputPath = inputPath; } /* * 下载用的Action应该返回一个InputStream实例,该方法对应在result里的inputName属性为 * getDownloadFile */ public InputStream getDownloadFile() { return ServletActionContext.getServletContext().getResourceAsStream( "/upload/Struts2.txt"); } public String execute() throws Exception {
return SUCCESS;
}
}
下面我们在来看一下struts.xml的配置:
<action name="down" class="cn.csdn.hr.up.action.DownAction"> <!-- 配置结果类型为stream的结果 --> <result name="success" type="stream"> <!-- 指定被下载文件的文件类型 --> <param name="contentType">text/plain </param> <!-- 指定下载文件的文件位置 --> <param name="contentDisposition">attachment;filename="Struts2.txt"</param> <param name="inputName">downloadFile</param> </result> </action>
这个action特殊的地方在于result的类型是一个流(stream ),配置stream类型的结果时,因为无需指定实际的显示的物理资源,所以无需指定location 属性,只需要指定inputName 属性,该属性指向被下载文件的来源,对应着Action类中的某个属性,类型为InputStream。下面则列出了和下载有关的一些参数列表:
参数说明
contentType
内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片
inputName
下载文件的来源流,对应着action类中某个类型为Inputstream的属性名,例如取值为inputStream 的属性需要编写getInputStream()方法
contentDisposition
文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。取值为:attachment;filename="struts2.txt" ,表示文件下载的时候保存的名字应为struts2.txt 。如果直接写filename="struts2.txt" ,那么默认情况是代表inline ,浏览器会尝试自动打开它,等价于这样的写法:inline; filename="struts2.txt"
bufferSize
下载缓冲区的大小
在这里面,contentType 属性和contentDisposition 分别对应着HTTP响应中的头Content-Type 和Content-disposition 头
当然,在很多的时候我们一般都不是把文件名写死在xml配置当中的,我们一般会在action中定义一个变量downfilename,储存这个文件名,然后再xml配置:
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
我们经常在中文下载中,出现文件名乱码的问题,这个问题是很多人都常见的,具体的很好的解决方法也没有,但我以前用的时候尝试着给他重新编码,这样可以解决大部分时候的中文下载乱码问题,但有时候也不行的。具体重新编码就是:
downFileName = new String(downFileName.getBytes(), "ISO8859-1");
好了,struts2文件上传和下载就简单介绍到这,文章中有什么不对或者错误的地方,欢迎大家指正。
相关文章推荐
- Java程序员从笨鸟到菜鸟之(七十一)细谈struts2(十三)struts2实现文件上传和下载详解
- 细谈struts2(十三)struts2实现文件上传和下载详解
- Java程序员从笨鸟到菜鸟之(六十九)细谈Hibernate(十七)Hibernate实现分页和综合查询详解
- Java程序员从笨鸟到菜鸟之(三十五)细谈struts2(一)自己实现struts2框架
- Java程序员从笨鸟到菜鸟之(四十七)细谈struts2(九)内置拦截器和自定义拦截器详解(附源码)
- Java程序员从笨鸟到菜鸟之(五十三)细谈Hibernate(四)Hibernate常用配置文件详解
- Java程序员从笨鸟到菜鸟之(四十八)细谈struts2(十)ognl概念和原理详解
- Java程序员从笨鸟到菜鸟之(四十八)细谈struts2(十)ognl概念和原理详解
- Java程序员从笨鸟到菜鸟之(四十八)细谈struts2(十)ognl概念和原理详解
- Java程序员从笨鸟到菜鸟之(五十三)细谈Hibernate(四)Hibernate常用配置文件详解
- Java程序员从笨鸟到菜鸟之(七十二)细谈Spring(四)利用注解实现spring基本配置详解
- Java程序员从笨鸟到菜鸟之(四十六)细谈struts2(八)拦截器的实现原理及源码剖析
- Java程序员从笨鸟到菜鸟之(四十六)细谈struts2(八)拦截器的实现原理及源码剖析
- Java程序员从笨鸟到菜鸟之(四十八)细谈struts2(十)ognl概念和原理详解
- .Java程序员从笨鸟到菜鸟之(四十七)细谈struts2(九)内置拦截器和自定义拦截器详解(附源码) 分类: 学习专区 框架Struts2 Java程序员从笨鸟到菜鸟 2012-05-08 12:
- Java程序员从笨鸟到菜鸟之(五十三)细谈Hibernate(四)Hibernate常用配置文件详解
- Java程序员从笨鸟到菜鸟之(五十三)细谈Hibernate(四)Hibernate常用配置文件详解
- Java程序员从笨鸟到菜鸟之(五十三)细谈Hibernate(四)Hibernate常用配置文件详解
- Java程序员从笨鸟到菜鸟之(五十三)细谈Hibernate(四)Hibernate常用配置文件详解
- Java程序员从笨鸟到菜鸟之(七十二)细谈Spring(四)利用注解实现spring基本配置详解