linux struts2 乱码,解决Struts2下载中文文件乱码问题

通过《Struts2文件下载实例》的学习,读者已经学会了如何使用 Struts2 框架实现文件下载,但是细心的读者会发现,如果上传一个中文名称的文件(如文本文件.txt),再次下载此文件时,页面会报出 500 错误,如图 1 所示。

1ee36f2edca2d0d074b07b3aa6c83f37.png

图 1  中文文件下载报错

之所以出现图 1 中的错误,是因为所要下载的文件不存在,导致 inputStream 为 null,所以报出了 500 错误。这里读者一定会很费解,明明上传了一个新文件,并可以确认文件在文件夹中是存在的,那么为什么还会报出此错误呢?

如果在 SimpleDownLoadAction 类的第 21 行代码中设置断点,并采用 Debug 模式调试执行程序,会发现传递到 Action 中的中文名称变成了乱码,如图 2 所示。

464348c3199b99080ce142c02c33e83a.png

图 2  中文乱码

从图 2 中可以看到,页面中传递的“测试.txt”已经变为“æµè¯.txt”,这说明在传递过程中,中文名称发生了乱码。然而在实际应用中,下载中文文件是不可避免的。下面本节将通过一个具体的案例讲解如何使用 Struts2 框架下载中文文件。

1)创建文件下载页面

在项目的 WebContent 目录中创建一个名称为 filedownload.jsp 的文件,在文件中添加一个中文链接,其代码如下所示:

测试.txt

2)创建 Action 类

在 com.mengma.action 包中新建一个名称为 FileDownLoadAction 的类,该类是用于下载文件的 Action,编辑后如下所示。

package com.mengma.action;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

import org.apache.struts2.ServletActionContext;

import sun.misc.BASE64Encoder;

import com.opensymphony.xwork2.ActionSupport;

public class FileDownLoadAction extends ActionSupport {

private String filename; // 代表下载文件的名称

private String contentType; // 下文件的 MimeType

/**

* 获取文件的名称

*/

public String getFilename() throws IOException {

// 对不同浏览器传过来的文件名进行编码

return encodeDownloadFilename(filename, ServletActionContext

.getRequest().getHeader("User-Agent"));

}

public void setFilename(String filename)

throws UnsupportedEncodingException {

// 对文件名称编码

filename = new String(filename.getBytes("iso8859-1"), "utf-8");

this.filename = filename;

}

/**

* 获取文件的类墩

*/

public String getContentType() {

return ServletActionContext.getServletContext().getMimeType(filename);

}

public void setContentType(String contentType) {

this.contentType = contentType;

}

// 定义了返回InputStream的方法,该方法作为被下载文件的入口

public InputStream getFileDownload() {

// 要下载的文件的路径

String filepath = "/upload/" + filename;

return ServletActionContext.getServletContext().getResourceAsStream(

filepath);

}

/*

* 对不同浏览器传过來的文件名称进行转码

* @param name文件名窗;

* @param agenr浏览器

* @return转码后的名称

*/

public String encodeDownloadFilename(String name, String agent)

throws IOException {

if (agent.contains("Firefox")) { // 火孤浏览器

name = "=?UTF-8?B?"

+ new BASE64Encoder().encode(name.getBytes("utf-8")) + "?=";

} else { // IE及其他浏览器

name = URLEncoder.encode(name, "utf-8");

}

return name;

}

}

上述代码中,声明了 filename 和 contentType 两个属性,分别代表所要下载文件的名称和类型。

在 filename 属性的 getter() 方法中,通过 encodeDownloadFilename(String name,String agent) 方法对不同浏览器传过来的名称进行编码,在其 setter() 方法中,对其文件名称又进行了一次编码,使文件名称统一为 UTF-8 编码格式。

通过 contentType 属性的 getContentType() 方法获取了文件的类型,并在 getFileDownload() 方法中定义了要下载的文件路径,并返回一个输入流。

3)修改配置文件

在 struts.xml 文件中,增加 FileDownLoadAction 的配置信息,其代码如下所示:

${contentType}

attachment;filename=${filename}

filedownload

在上述配置代码中,${contentType} 和 ${filename} 会在项目运行时,将 action 中的对象属性动态地填充在 ${} 中间部分,相当于 action.getContentType() 和 action.getFilename(),通过此种方式动态地获取文件的类型和名称。

4)运行程序并查看结果

在浏览器的地址栏中输入地址 http://localhost:8080/struts2Demo06/filedownload.jsp,成功访问后,单击页面中的“测试.txt”链接,其效果如图 3 所示。

3a44140c77e81b72cef7a1bd764c90c1.png

图 3  中文文件下载

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值