`
laotu5i0
  • 浏览: 145564 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

理解和灵活应用 Struts2 的文件下载功能

    博客分类:
  • java
阅读更多

文件下载给我们最直接的概念就是,给个文件链接点击就下载。似乎太简单,然而 Struts2 却把它作为一个独立的学问来对待,理由有四:

1. 文件名为中文时,直接点击下载,链接可能会走样(某些浏览器,URL 编码的问题),致使无法下载。
2. 不总是从下载实际的文件,文件内容有时候是动态生成的,如数据库中的内容。
3. 对于知名的文件类型不让浏览器直接打开,而是出现下载对话框保存文件。例如,要下载的文件是 .txt 的,可能直接就在浏览器中显示其内容。
4. 需要授权才能下载文件时

当然对于以上若干问题,Servlet/JSP 都能通过正确的 URL 编码,响应头设置、权限代码控制解决,只是 Struts2 让我们处理起来更方便了,内部原理自然是一样的。

先来看下 Servlet 如何实现文件下载的,直接见代码:

view source
<object id="highlighter_304590_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash"> <param name="_cx" value="423"> <param name="_cy" value="423"> <param name="FlashVars"> <param name="Movie" value="/Files/framework/clipboard.swf.zip"> <param name="Src" value="/Files/framework/clipboard.swf.zip"> <param name="WMode" value="Transparent"> <param name="Play" value="0"> <param name="Loop" value="-1"> <param name="Quality" value="High"> <param name="SAlign"> <param name="Menu" value="0"> <param name="Base"> <param name="AllowScriptAccess" value="always"> <param name="Scale" value="ShowAll"> <param name="DeviceFont" value="0"> <param name="EmbedMovie" value="0"> <param name="BGColor"> <param name="SWRemote"> <param name="MovieData"> <param name="SeamlessTabbing" value="1"> <param name="Profile" value="0"> <param name="ProfileAddress"> <param name="ProfilePort" value="0"> <param name="AllowNetworking" value="all"> <param name="AllowFullScreen" value="false"></object>
print?
01.PrintWriter out = response.getWriter();
02.  
03.//不管实际类型,待下载文件 ContentType 统一指定为 application/octet-stream
04.response.setContentType("application/octet-stream");
05.  
06.//中文文件名必须转码为 ISO8859-1,否则为乱码
07.String fileName = new String("文本文件.txt".getBytes(), "ISO8859-1");
08.  
09.//作为附件下载,相应的 "inline;filename = "+fileName 是在线(浏览器中显示内容)打开
10.response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
11.  
12.//因为文件编码也为 ISO8859-1,所以内容须转码成 ISO8859-1,尚不知如何控制下载文本文件的编码
13.//或有谁知道的,还请告诉我一下。 文件内容可以从物理文件中来,或者数据库中读取填入等等
14.out.write(new String("Servlet 文件下载测试".getBytes(), "ISO8859-1"));
15.  
16.out.close();


知道了上面各行的含义,再来看下 Struts2 的解决方式,其实不过是把某些代码的功能移入到了配置文件而已。在李刚所著的《Struts 2 权威指南》中说 Struts 实现文件下载是由一个 download 拦截器。其实不然,只是一个 StreamResult(org.apache.struts2.dispatcher.StreamResult) 而已,也不像实现文件上传那样要额外的 JAR 包。在 StreamResult 中有以下几个默认属性要留意一下:

    public static final String DEFAULT_PARAM = "inputName";

 

    protected String contentType = "text/plain";
    protected String contentDisposition = "inline";
    protected String inputName = "inputStream";
    protected InputStream inputStream;
    protected int bufferSize = 1024;

StreamResult 的实现细节敬请阅读它的源代码,实现过程一言以蔽之就是:从 inputStream 获取内容,以相应的 contentType、contentDisposition 和 bufferSize 输出给浏览器,对 contentType 和 contentDisposition 的相应设置就能实现文件下载,可对照前面 Servlet 的实现。看个实际的例子吧。

struts.xml 中 Action 的配置,假定 Action 类为 com.unmi.DownLoadAction

view source
<object id="highlighter_544051_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash"> <param name="_cx" value="423"> <param name="_cy" value="423"> <param name="FlashVars"> <param name="Movie" value="/Files/framework/clipboard.swf.zip"> <param name="Src" value="/Files/framework/clipboard.swf.zip"> <param name="WMode" value="Transparent"> <param name="Play" value="0"> <param name="Loop" value="-1"> <param name="Quality" value="High"> <param name="SAlign"> <param name="Menu" value="0"> <param name="Base"> <param name="AllowScriptAccess" value="always"> <param name="Scale" value="ShowAll"> <param name="DeviceFont" value="0"> <param name="EmbedMovie" value="0"> <param name="BGColor"> <param name="SWRemote"> <param name="MovieData"> <param name="SeamlessTabbing" value="1"> <param name="Profile" value="0"> <param name="ProfileAddress"> <param name="ProfilePort" value="0"> <param name="AllowNetworking" value="all"> <param name="AllowFullScreen" value="false"></object>
print?
01.<action name="download" class="com.unmi.action.DownloadAction">
02.    <result name="success" type="stream"><!--type 为 stream 应用 StreamResult 处理-->
03.        <param name="contentType">application/octet-stream</param><!--默认为 text/plain-->
04.          
05.        <!-- 默认就是 inputStream,它将会指示 StreamResult 通过 inputName 属性值的 getter 方法,
06.              比如这里就是 getInputStream() 来获取下载文件的内容,意味着你的 Action 要有这个方法 -->
07.        <param name="inputName">inputStream</param>
08.          
09.        <!-- 默认为 inline(在线打开),设置为 attachment 将会告诉浏览器下载该文件,filename 指定下载文
10.              件保有存时的文件名,若未指定将会是以浏览的页面名作为文件名,如以 download.action 作为文件名,
11.              这里使用的是动态文件名,${fileName}, 它将通过 Action 的 getFileName() 获得文件名 -->
12.        <param name="contentDisposition">attachment;filename="${fileName}"</param>
13.        <param name="bufferSize">4096</param><!-- 输出时缓冲区的大小 -->
14.    </result>


说明:对于上面的配置其他参数可以用默认值,关键就是 contentDisposition 要设置为 attachment 才能提示下载,同时用 filename 指定文件名,若直接指定非动态的文件名。

DownloadAction 代码,需要实现 getInputStream() 返回输入流;因前面用的动态文件名,所以须加上 getFileName() 返回文件名,若非动态文件名,则该方法可省去。

view source
<object id="highlighter_542863_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash"> <param name="_cx" value="423"> <param name="_cy" value="423"> <param name="FlashVars"> <param name="Movie" value="/Files/framework/clipboard.swf.zip"> <param name="Src" value="/Files/framework/clipboard.swf.zip"> <param name="WMode" value="Transparent"> <param name="Play" value="0"> <param name="Loop" value="-1"> <param name="Quality" value="High"> <param name="SAlign"> <param name="Menu" value="0"> <param name="Base"> <param name="AllowScriptAccess" value="always"> <param name="Scale" value="ShowAll"> <param name="DeviceFont" value="0"> <param name="EmbedMovie" value="0"> <param name="BGColor"> <param name="SWRemote"> <param name="MovieData"> <param name="SeamlessTabbing" value="1"> <param name="Profile" value="0"> <param name="ProfileAddress"> <param name="ProfilePort" value="0"> <param name="AllowNetworking" value="all"> <param name="AllowFullScreen" value="false"></object>
print?
01.package com.unmi.action;
02.  
03.import java.io.*;
04.import java.text.*;
05.import java.util.Date;
06.  
07./**
08. * 文件下载的 Action 
09. * @author Unmi
10. */
11.public class NetbookSerialAction {
12.  
13.    public String execute() throws Exception {
14.        //这里可加入权限控制
15.        return "success";
16.    }
17.  
18.    //获得下载文件的内容,可以直接读入一个物理文件或从数据库中获取内容
19.    public InputStream getInputStream() throws Exception {
20.        //return new FileInputStream("somefile.rar"); 直接下载 somefile.rar
21.  
22.        //和 Servlet 中不一样,这里我们不需对输出的中文转码为 ISO8859-1
23.        return new ByteArrayInputStream("Struts2 文件下载测试".getBytes());
24.    }
25.  
26.    //对于配置中的 ${fileName}, 获得下载保存时的文件名
27.    public String getFileName() {
28.        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
29.        String fileName = "序列号(" + df.format(new Date()) + ").txt";
30.        try {
31.            //中文文件名也是需要转码为 ISO8859-1,否则乱码
32.            return new String(fileName.getBytes(), "ISO8859-1");
33.        } catch (UnsupportedEncodingException e) {
34.            return "impossible.txt";
35.        }
36.    }
37.}



谨记一个就是,要想下载的文件名不乱码就要以 ISO8859-1 字符集进行转码,内容会否乱码可在调试中解决。

好啦,启动服务,访问 http://localhost:8080/teststruts2/download.action,浏览器便会提示下载 序列号(2009-06-17).txt,内容为:“Struts2 文件下载测试”。

 

分享到:
评论

相关推荐

    Struts2接口文档

    总的来说,Struts2接口文档是学习和使用Struts2框架不可或缺的工具,它能帮助开发者高效地理解和使用框架提供的各种组件和接口,提升开发效率,减少错误,并有助于深入理解MVC模式在实际项目中的应用。通过仔细研读...

    struts1和struts2分别实现文件上传下载功能

    Struts1和Struts2是两个非常著名的Java Web框架,它们都提供了处理文件上传和下载的功能,但实现方式有所不同。本文将深入探讨这两个框架在文件操作方面的具体实现。 首先,让我们了解一下Struts1中的文件上传功能...

    struts2 API帮助文档

    这个API帮助文档是开发者在使用Struts2框架时的重要参考资料,它详细阐述了框架的各种组件、类库和方法,有助于理解并有效利用Struts2的功能。 1. **Struts2核心组件** - `struts2-core`:这是Struts2框架的核心...

    Struts2+Jquery+Ajax

    通过理解MVC模式、熟练掌握Struts2的配置和Action处理、灵活运用Jquery和Ajax,可以大大提高开发效率,提升用户使用体验。在实际开发过程中,还需要关注安全问题,如Struts2的安全漏洞,确保应用的稳定性和安全性。

    Struts2 Struts2 超好的Struts2 pdf 文档

    通过阅读这份“超好的Struts2 pdf 文档”,开发者不仅可以掌握Struts2的基本使用,还能深入理解其设计理念,提升Web应用的开发效率和质量。在实际项目中,结合Struts2的灵活性和强大的功能,可以构建出稳定、高效的...

    Struts2帮助文档

    总的来说,"Struts2帮助文档"是一份宝贵的资源,它将引导你探索Struts2的强大功能,助你在开发高效、稳定的Web应用时游刃有余。通过深入阅读和实践,你不仅可以掌握Struts2的使用,还能提升Java web开发的整体能力。

    Struts2-API+Struts2中文帮助文档

    此压缩包包含的"Struts2-API"和"Struts2中文帮助文档"是学习和开发Struts2应用的重要资源。 Struts2-API文档详细列出了框架的所有公共接口和类,这是开发者理解并使用Struts2核心组件的基础。例如,`ActionSupport`...

    struts2jar.zip

    通常,Struts2的核心库和其他依赖库会以JAR(Java Archive)文件的形式包含在项目中,这些JAR文件包含了框架的所有类和方法。开发者需要将这些JAR文件添加到项目的类路径中,以便能够使用Struts2的功能。文件可能会...

    struts2-showcase.rar

    Struts2-showcase是一个用于演示和学习Apache Struts2框架功能的开源项目。这个压缩包“struts2-showcase.rar”包含了完整的源代码,旨在帮助开发者深入理解Struts2框架的工作原理及其各种特性。以下是对Struts2和...

    struts2简单例子

    这个“struts2简单例子”是初学者理解Struts2工作原理和核心概念的一个很好的起点。让我们深入探讨一下Struts2的基础知识。 1. **MVC架构**: MVC模式是软件设计中的一个经典模式,它将应用逻辑分为三个主要部分:...

    Struts2基础应用二

    Struts2是Java Web开发中一个非常重要的框架,它的出现为开发者提供了强大...总的来说,学习和理解Struts2的基础应用,不仅能够帮助开发者构建功能完善的Web应用,也能为后续深入学习其他Java Web框架打下坚实的基础。

    struts2 文件的上传和下载

    总的来说,Struts2的文件上传和下载功能强大且灵活,但需要对HTTP协议、文件流操作和服务器文件系统有基本理解。实际开发时,还需要考虑错误处理、安全性和性能优化,比如限制文件大小、检查文件类型、防止路径遍历...

    Struts2视频教程

    - **定义与特点**:Struts2是一款基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架,它继承了Struts1的优点,同时在设计上更加灵活、易用,支持拦截器、类型转换、文件上传等特性。Struts2使用过滤...

    struts2开发文档

    这个压缩包文件包含了关于Struts2开发的各种文档,是开发者深入理解并熟练运用Struts2的重要参考资料。 首先,Struts2的核心是基于MVC(Model-View-Controller)设计模式的,它将业务逻辑、数据模型和用户界面分离...

    最简单的struts2文件

    在这个“最简单的struts2文件”中,我们可以找到构建一个基本Struts2应用所需的组件和配置。下面将详细解释Struts2的核心概念和关键组成部分。 1. **Action类**: 在Struts2中,业务逻辑主要由Action类执行。...

    struts2的各种jar包

    Struts2是一个强大的Java web应用程序框架,用于构建和管理MVC(模型-视图-控制器)架构的应用程序。它在Java社区中广泛使用,因...理解并熟练掌握这些知识点,将有助于你高效地开发和维护基于Struts2的Java web应用。

    STRUTS2学习文档

    Struts2是一个基于MVC(Model-View-Controller)设计模式的Java web应用程序框架,它在Struts1的基础上进行了很多改进和增强,提供了更强大的功能和更好的灵活性。这个"STRUTS2学习文档"显然是一个关于如何理解和...

    struts2包下载

    Struts2是一个强大的Java web应用程序框架,用于构建和...通过深入理解和熟练运用Struts2,开发者可以创建高效、可维护的Web应用。在使用过程中,保持框架的版本更新和遵循最佳实践是确保应用安全性和稳定性的关键。

    Struts2.rar文件

    Struts2.2.1是该框架的一个版本,提供了丰富的功能和改进,以提高开发效率和应用性能。 在"Struts2.rar"文件中,我们可以期待找到以下核心知识点: 1. **拦截器(Interceptors)**:Struts2的一大特色是它的拦截器...

    Struts2的综合应用

    Struts2是一个强大的MVC(模型-视图-控制器)框架,它被广泛应用于Java Web开发中,提供了灵活的架构来构建可维护性和扩展性良好的应用程序。本综合应用实例主要展示了如何利用Struts2框架与MySQL数据库进行集成,...

Global site tag (gtag.js) - Google Analytics