Struts2总结---文件上传和下载详解 (9)

来源:互联网 发布:淘宝销售额怎么算 编辑:程序博客网 时间:2024/06/06 01:01

   文件上传和文件下载是我们在web应用程序中常用的两个功能,在Java中,实现这两种功能的方式也有很多种,其中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表示XMLimage/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");      





0 0
原创粉丝点击