• 1. 第八章:Struts 2文件上传下载 主讲:刘雷
  • 2. 本章内容Struts2单文件上传 Struts2多文件上传 Struts2文件下载
  • 3. 表单enctype属性application/x-www-form-urlencoded: 默认值,只要是能输出网页的服务器端环境都可以 multipart/form-data: 上传二进制数据,只有使用multipart/form-data ,才能完整的传递文件数据,进行上传操作
  • 4. 两个上传框架Common-FileUplaod:apache的开源项目,由jakarta项目组开发。 功能强大,简单易用,可以实现一次上传一个或多个文件,并可限制文件大小。 COS:O‘Reilly公司开发的开源框架 会不定期的增加一些新功能。
  • 5. 下载Common-FileUplaod框架下载Common-FileUplaod框架地址: http://jakarta.apache.org/commons/fileupload/ 下载commons-fileupload-1.2-bin.zip文件 解压后得到commons-fileupload-1.2.jar http://jakarta.apache.org/commons/io/ 下载commons-io-1.3.2-bin.zip文件 解压后得到commons-io-1.3.2.jar
  • 6. 基于表单的文件上传注意:上面是基于表单的上传,在form标签中有一个必须的属性值设置:enctype. 如果要做文件上传功能必须将enctype值设为multipart/form-data. 此外,文件上传还需要二个JAR文件支持:
  • 7. 文件上传页面upload.jsp
    文件:
    或者 <%@ taglib uri="/struts-tags" prefix="s" %>
  • 8. 上传Action类UploadAction
  • 9. 上传Action类UploadAction
  • 10. Struts.xml
  • 11. 处理错误提示以中文显示 如果上传文件大于2M时,在页面上就出现了一堆英文的错误信息,大致是:the request was rejected because its size....exceeds the configured maximum...并且在fieUpload中将来自MultiPartRequestWrapper型request对象的错误信息给加到了Action的错误中。 这时候,你在ApplicationResources.properties中自定义的上传文件过大的错误信息根本不起作用。原因就如书上所言,在底层commons-fileupload组件中就把异常给抛出来了文件根本没被上传,所以到了fileUpload拦截器时,根据取不到文件,当然也就没法对文件的类型和大小进行判断了。
  • 12. 注意
  • 13. 解决页面the request was rejected because its size错误提示
  • 14. 使用数组同时上传多个文件
  • 15. 使用数组同时上传多个文件
  • 16. 使用数组同时上传多个文件
  • 17. 使用数组同时上传多个文件
  • 18. 使用数组同时上传多个文件
  • 19. 使用list同时上传多个文件
  • 20. 使用list同时上传多个文件
  • 21. 使用list同时上传多个文件
  • 22. 使用list同时上传多个文件
  • 23. 使用list同时上传多个文件
  • 24. 文件下载有的同学可能会想,我只要设置一个超链接,不就可以下载文件了吗?确实如此,但是通过超链接下载文件,暴露了下载文件的真实地址,不利于对资源进行安全保护;而且利用超链接下载文件,服务器端的文件只能存放在Web应用程序所在的目录下。 利用程序编码实现下载,可以增加安全访问控制,对经过授权认证的用户提供下载,还可以任意提供下载的数据,我们可以将文件放到Web应用程序以外的目录中,也可以将文件保存到数据库中。 利用程序下载也非常简单,只需要按照如下的方式设置三个报头域就可以了: Content-Type:application/x-msdownload Content-Disposition:attachment;filename=downloadfile Content-Length:filesize 浏览器在接收到上述的报头信息后, 就会弹出文件下载对话框,让你将文件保存到本地硬盘。
  • 25. Struts2对文件下载的支持Struts2通过org.apache.struts2.dispatcher.StreamResult结果类型来支持文件下载,使得原本编写就简单的下载程序变得更加简单了。 StreamResult结果类型利用HttpServletResponse对象返回的ServletOutputStream对象向客户端输出下载文件的二进制数据,它有下列参数: contentType:发送给Web浏览器的数据流的MIME类型(默认是text/plain),即下载文件内容类型 contentLength:数据流的长度,以字节为单位(浏览器显示一个进度栏),即下载文件的长度。 contentDisposition:用于控制文件下载的一些信息,可选择的设置包括:inline;filename=“下载文件名”和attachment;filename=“下载文件名”,filename指定下载的文件名。Inline表示下载文件在本页面内部打开,attachement表示弹出”文件下载”对话框。不过,这也不是绝对的,对于浏览器能够显示的下载文件是这样的,对于浏览器不支持的下载类型,即使使用inline选项,仍然会弹出”文件下载”对话框。 contentDisposition的默认值是inline. inputName:Action中用来下载文件的属性的名字,该属性的类型是InputStream.默认值是inputStream. bufferSize:文件数据从输入复制到输出的缓冲区的大小,默认为1024字节。
  • 26. 举例streamResult结果类型已经在struts-default文件中定义,逻辑名为stream.我们看一个使用stream结果类型的例子:
  • 27. 在struts2中实现文件下载
  • 28. 配置struts.xml
  • 29. 页面download.jsp工程层次图
  • 30. 注意如果你要下载任意目录下的文件(而不仅限于Web应用程序目录),那么只需要修改action中返回文件输入流的方式即可,例如:return new FileInputStream(inputPath). 在实际应用中,下载的文件不应该在struts.xml中配置,如果是这样,那就等于将DownLaodAction的功能限制为了只下载一个文件。下载文件的选取应该通过编码来实现,根据浏览器传来的下载请求,查询配置文件或数据库,获取真实下载文件数据,构造InputStream对象。
  • 31. 改进文件下载程序对于下载的文件名、下载的文件类型都是在struts.xml文件中配置的,如果有许多不同类型的文件要提供给用户下载,那么这种方式显然有失灵活性。 为了能动态设置文件类型和下载的文件名,我们可以编写一个拦截器,在Action执行完毕,result执行之前,动态添加StreamResult的参数。为了能够在result执行之前截获调用,我们需要用到PreResultListener,该接口可以通过ActionInvocation注册,在Action执行完毕,result执行之前得到一个回调。 PreResultListener需要在拦截器中进行注册,所以我们需要编写一个拦截器,然后在拦截器方法中注册一个PreResultListener实例。
  • 32. 编写DownLoadInterceptor拦截器类新建DownLoadInterceptor类,继承AbstractInterceptor类,代码如下:
  • 33. 说明在上面的代码中,我们定义了一个匿名的内部类实现PreResultListener接口,然后调用ActionInvocation的addPreResultListener方法注册PreResultListener实例。 在匿名内部类的beforeResult()方法中,不能通过invocation.getResult()来得到Result对象,因为此时Result对象还没有被创建,为null.为了修改传递给StreamResult的参数,可以通过如下的方法调用来得到Result的配置信息,Result的配置封装在ResultConfig对象中。 向ResultConfig对象添加参数,可以在这个对象上调用addParam()方法。
  • 34. struts.xml配置
  • 35. 谢谢!