struts2自学第三课-struts2文件下载

来源:互联网 发布:休闲网游推荐 知乎 编辑:程序博客网 时间:2024/05/02 00:13


2012-8-30 14:30:22
-----
1 struts下载例子一:指定某个文件下载(写死在struts.xml中了,这种方式可以入门时学习,估计平时不用。)
下载操作:jar包,跟上传文件所用jar包相同。
关键文件:struts.xml和action类
struts.xml:
<action>
 <param name="filePath">/upload/中解析xml的方式2.txt</param>  //参数-告诉action将要下载的文件的路径
 
 <result name="success" type="stream">    //这里写了name,action就要写execute()方法,(name属性可以不写的!)因为 public InputStream getXX()不能返回"success"。type是[文件下载] 的固定写法
  
  //result中有3个参数1个返回页面,返回页面可选,参数亦可在action中设置,写在这里,struts会自动把参数值注入到action的属性中(属性可能定义在ActionSupport类中)
  
  //参数一:
  <param name="contentType">image/jpg</param>   //下载的文件的类型,固定写法,如*.jpg的就要写成image/jpg *.txt 等也有它们自己对应的Type值。
  //参数二:
  <param name="inputName">xx</>   //这里的xx就是action中public InputStream getXX() 的xx,但xml中首字母要小写。(如:xml——inputName">apple</>  action——getApple();)
  //参数三:
  <param name="contentDisposition">attachment;filename="2.txt"</param>  
  //
 
 </>//result结束
</>

------------------上述的下载方式是指定一个目标文件来下载,而且文件名、文件类型都在struts.xml中唯一指定了。------------------------
以下,在action中动态指定下载的目标文件、动态的下载文件名和后缀名。
下载方式二:

(1)在struts.xml中配置action时,
<result type="stream" name="success">
 <!--只配置这一个参数,拦截器会在执行完action的execute后,根据这个参数值调用该属性的getXX方法。-->
 <!--name的值固定,参数值跟acton中的getXX的XX匹配,这里的xX首字母小写-->
 <param name="inputName">xX</param>
 /index.jsp
</result>

(2)在action类中,定义一个属性String filePath及其getter、setter,用于接收从页面传过来的“目的文件的相对路径”。即,jsp传来一参数,动态指定要下载哪个文件。
注意,jsp传过来的filePath的值,是个相对于WebContent文件夹的相对路径,且目标文件放在这个相对路径下。如/uploadFloed/test.txt

(3)在action中定义action入口execute,返回"success"
在action中定义public InputStream getXX()方法,
方法体内的主要代码时:
 a.response.setHeader();//用这个方法设置返回给浏览器的html的文件头属性信息。包括2个:
 Content-Type(文件类型,如"image/jpg",根据目标文件动态获取"image/jpg")
 Content-Disposition (下载方式,下载文件时的默认文件名,如:"attachment;filename="2.txt" ","2.txt"可以根据目标文件的文件名动态赋值,也可以自定义)
 
 b.根据相对路径,获取目标文件,作为InputStream返回。(固定写法)
 return ServletActionContext.getServletContext.getResourceAsStream(filePath);  //filePath就是从页面传来的目标文件的相对路径


下载常见异常
Can not find a java.io.InputStream with the name [fileInputStream] in the invocation stack. Check the <param name="inputName"> tag specified for this action.
就是说,你要下载的文件,它不能整整InputStream返回,原因可能是文件路径错误,如文件名、路径名,文件不存在等,还有可能是,struts.xml中的<result>写了name="success",但action中没有execute()方法。

可以只在struts.xml中配置一个result参数(inputName-fileStream),但在getFileStream()方法中调用setHeader()时出错,导致在下载窗体上显示的下载文件名为:download2.actoin
出现download2.action的情况是,没有把struts.xml中的contentDisposition参数替换过来,即setHeader写错了:
getResponse().setHeader("contentDisposition", "attachment;filename="+new File(this.getFilePath()).getName());是错误的
getResponse().setHeader("Content-Disposition", "attachment;filename="+new File(this.getFilePath()).getName());才是在setHeader中的正确写法。


测试时发现的一些现象:
1 上传4M左右的mp3,上传失败。
后台 警告: the request was rejected because its size (4402297) exceeds the configured maximum (2097152)

解决办法:在struts.xml中设置最大上传文件
<struts>
 <!-- 设置全局的上传文件的最大文件 -->
 <constant name="struts.multipart.maxSize" value="9000000"/>
 <package...></package>
</struts>

struts.multipart.maxSize默认2M,当maximumSize大于2M时,必须设置struts.multipart.maxSize的值大于maximumSize。


2 下载含有中文文件名的文件,在下载提示框中,中文被空格代替了。
http://www.cnblogs.com/quanjia/archive/2010/11/01/1866753.html
  String guessCharset = getRequest().getCharacterEncoding();
   System.out.println("char encoding:"+getRequest().getCharacterEncoding());
   fileName = new String(name.getBytes(guessCharset), "ISO8859-1");
  return fileName;
通过request可以获得客户端的浏览器页面默认编码。

3 如果是要下载文件,就在struts.xml中配置inputName参数,让拦截器调用getXX方法,如果是点击文件,让它直接在页面上打开显示,则通过以下方式写到response,不需要在struts.xml中配置inputName。
fis = new FileInputStream(downloadFile);
 
    os = this.getResponse().getOutputStream();
    byte[] b = new byte[2048];
    int len = -1;
    while ((len = fis.read(b, 0, b.length)) != -1) {
     os.write(b, 0, len);
     os.flush();
    }
    fis.close();
    os.close();
====================
------------
ok