struts2多文件动态下载及中文解决方案

来源:互联网 发布:北京网站排名优化软件 编辑:程序博客网 时间:2024/05/17 07:21

首先注明参考

1.浪曦网风中叶讲师的Struts2应用开发系列视频教程(在此,扩展下载部分)

2.Google 对 http://www.xileju.biz/index.php/74/ 的缓存。 在 2008年10月31日 19:44:01 GMT 的快照。(原文网站居然连不上)

 

上传部分,已经在视频中跟风中叶老师学了遍,下面是文件下载及文件名为中文的时候浏览器出现乱码的解决方案。

download2.jsp

  1. <%@ page language="java" import="java.io.File" contentType="text/html; charset=UTF-8"
  2.     pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10.     <% 
  11.     //取得服务器"/download/file"目录的物理路径 
  12.     String path = request.getRealPath("/upload");
  13.     //取得"/download/file"目录的file对象 
  14.     File file = new File(path); 
  15.     //取得file目录下所有文件 
  16.     File[] files = file.listFiles(); 
  17.   
  18.    for (int i = 0; i < files.length; i++) { 
  19.   
  20.     String fname = files[i].getName();
  21.   
  22.     //对文件名进行url编码(UTF-8指明fname原来的编码,UTF-8一般由本地编码GBK代替) 
  23.      fname = java.net.URLEncoder.encode(fname, "UTF-8"); 
  24.   
  25.     out.println("<a href=download2.action?name=" + fname + "&len=" + files[i].length() + ">" 
  26.      + files[i].getName() + "</a><br>"); 
  27.     }
  28.    %>
  29. </body>
  30. </html>

Download2Action.java

  1. package com.test.action;
  2. import java.io.InputStream;
  3. import java.io.UnsupportedEncodingException;
  4. import org.apache.struts2.ServletActionContext;
  5. import com.opensymphony.xwork2.ActionSupport;
  6. public class Download2Action extends ActionSupport {
  7.     private static final long serialVersionUID = 9048071785232069492L;
  8.     private String fileName;
  9.     
  10.     private String flen;
  11.     
  12.     public String getFlen() {
  13.         return flen;
  14.     }
  15.     public void setFlen() {
  16.         this.flen = ServletActionContext.getRequest().getParameter("len");
  17.         System.out.println("setFlen: " + this.flen);
  18.     }
  19.     public void setFileName() {
  20.         //得到请求下载的文件名 
  21.         String fname = ServletActionContext.getRequest().getParameter("name");
  22.         try {
  23.             /* 
  24.              * 对fname参数进行UTF-8解码,注意:实际进行UTF-8解码时会使用本地编码,本机为GBK。 
  25.              * 这里使用request.setCharacterEncoding解码无效. 
  26.              * 只有解码了getDownloadFile()方法才能在下载目录下正确找到请求的文件 
  27.              * */
  28.             fname = new String(fname.getBytes("ISO-8859-1"), "UTF-8"); 
  29.         } catch (Exception e) {
  30.             e.printStackTrace();
  31.         }
  32.         this.fileName = fname;
  33.         System.out.println("setFileName: " + this.fileName);
  34.     }
  35.     /* 
  36.      * @getFileName 
  37.      * 此方法对应的是struts.xml文件中的: 
  38.      * <param name="contentDisposition">attachment;filename="${fileName}"</param> 
  39.      * 这个属性设置的是下载工具下载文件时显示的文件名, 
  40.      * 要想正确的显示中文文件名,我们需要对fileName再次编码 
  41.      * 否则中文名文件将出现乱码,或无法下载的情况 
  42.      * */
  43.     public String getFileName() throws UnsupportedEncodingException {
  44.         fileName=new String(fileName.getBytes(),"ISO-8859-1"); 
  45.         return fileName;
  46.     }
  47.     /* 
  48.      * @getDownloadFile 
  49.      * 此方法对应的是struts.xml文件中的: 
  50.      * <param name="inputName">downloadFile</param> 
  51.      * 返回下载文件的流,可以参看struts2的源码 
  52.      * */
  53.     public InputStream getDownloadFile() {
  54.         this.setFileName();
  55.         
  56.         this.setFlen();
  57.         return ServletActionContext.getServletContext().getResourceAsStream("/upload/" + fileName);
  58.     }
  59.     @Override
  60.     public String execute() throws Exception {
  61.         return SUCCESS;
  62.     }
  63. }

struts.xml  其中的EL表达式,是要注意的

  1.         <action name="download2" class="com.test.action.Download2Action">
  2.             <result name="success" type="stream">
  3.                 <param name="contentDisposition">attachment;filename="${fileName}"</param>
  4.                 <param name="contentLength">${flen}</param>
  5.                 <param name="inputName">downloadFile</param>
  6.             </result>
  7.         </action>

struts2中很多功能都为我们封装得很好了,只要我们给它属性注入相应的值,程序就能正常的跑起来。

文件的下载也不例外,我们找到这样一个类StreamResult,文件的下载由这个类全部为我们完成。其中有一个非常重要的属性contentDisposition,这个属性决定了下载窗口中显示的文件名,我们只要给这个属性注入正确的值,一切就OK。

而这个值需要去struts.xml文件里相应的action里去配置,由于是动态决定下载的文件,这里使用了EL表达式,${fileName},而fileName对应的则是Download2Action里的getFileName()方法,只要在这里给fileName相应的编码,struts2会自动寻找这个方法,并把相应的值注入到xml文件中,这样浏览器的下载窗口中就能正常显示我们想要的中文名。

原创粉丝点击