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

just posted @ 2009年4月01日 06:11 in struts2 , 4325 阅读

 

上传部分,已经在视频中跟风中叶老师学了遍,下面是文件下载及文件名为中文

的时候浏览器出现乱码的解决方案。

 

 

download2.jsp

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

 Download2Action.java:

 

package com.test.action;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class Download2Action extends ActionSupport {

    private static final long serialVersionUID = 9048071785232069492L;

    private String fileName;
     
    private String flen;
     
    public String getFlen() {
        return flen;
    }

    public void setFlen() {
        this.flen = ServletActionContext.getRequest().getParameter("len");
        System.out.println("setFlen: " + this.flen);
    }

    public void setFileName() {
        //得到请求下载的文件名 
        String fname = ServletActionContext.getRequest().getParameter("name");
        try {
            /* 
             * 对fname参数进行UTF-8解码,注意:实际进行UTF-8解码时会使用本地编码,本机为GBK。 
             * 这里使用request.setCharacterEncoding解码无效. 
             * 只有解码了getDownloadFile()方法才能在下载目录下正确找到请求的文件 
             * */

            fname = new String(fname.getBytes("ISO-8859-1"), "UTF-8")
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.fileName = fname;
        System.out.println("setFileName: " + this.fileName);
    }

    /* 
     * @getFileName 
     * 此方法对应的是struts.xml文件中的: 
     * <param name="contentDisposition">attachment;filename="${fileName}"</param> 
     * 这个属性设置的是下载工具下载文件时显示的文件名, 
     * 要想正确的显示中文文件名,我们需要对fileName再次编码 
     * 否则中文名文件将出现乱码,或无法下载的情况 
     * */

    public String getFileName() throws UnsupportedEncodingException {

        fileName=new String(fileName.getBytes(),"ISO-8859-1")

        return fileName;
    }

    /* 
     * @getDownloadFile 
     * 此方法对应的是struts.xml文件中的: 
     * <param name="inputName">downloadFile</param> 
     * 返回下载文件的流,可以参看struts2的源码 
     * */

    public InputStream getDownloadFile() {

        this.setFileName();
         
        this.setFlen();

        return ServletActionContext.getServletContext().getResourceAsStream("/upload/" + fileName);
    }

    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }
}
 

 

 

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

 

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

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

文件的下载也不例外,我们找到这样一个类StreamResult,文件的下载由这个类全部为我们完成。其中有一个非常重要

的属性contentDisposition,这个属性决定了下载窗口中显示的文件名,我们只要给这个属性注入正确的值,一切就OK。

而这个值需要去struts.xml文件里相应的action里去配置,由于是动态决定下载的文件,这里使用了EL表达式,${fileName}

而fileName对应的则是Download2Action里的getFileName()方法,只要在这里给fileName相应的编码,struts2会自动寻找这

个方法,并把相应的值注入到xml文件中,这样浏览器的下载窗口中就能正常显示我们想要的中文名。

 

  • 无匹配
  • 无匹配
qiqi 说:
2010年6月03日 00:58

你的方法我试过了,是对的。。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter