`
happinessmoon
  • 浏览: 75705 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

文件名乱码

阅读更多

http://www.blogjava.net/zamber/archive/2006/09/14/69752.html

Unicode网页中上传下载文件时发生文件名乱码的问题

最近有一个需要支持unicode的项目在上传和下载文件时遇到文件名乱码问题. 项目背景, 这个项目关键之处在于需要支持unicode以及支持Micorosoft Internet Explorer和Netscape Navigator两种浏览器. 为了解决这个问题, 我使用以下环境进行了尝试.

J2SE : 1.5.0_04
Tomcat : 5.5.17
Microsoft Internet Explorer 6.0 with SP2
Netscape Navigator 7.1
Firefox 1.5
以及Struts 1.1 (这个基本上对此次测试不是非常重要)

上传文件

对于unicode的页面进行上传文件的时候, 我使用一个text box和一个file upload box来进行比较. 页面如下.

utf-8 upload page

 通过此页面进行文件上传后, IE, NC以及FF所传输的数据均相同. 如下

Content-Type: multipart/form-data; boundary=---------------------------282302224217945
Content-Length: 27980

-----------------------------282302224217945
Content-Disposition: form-data; name="theText"

C:\縺ゅ≠縺ゅ≠.xls
-----------------------------282302224217945
Content-Disposition: form-data; name="theFile"; filename="縺ゅ≠縺ゅ≠.xls"
Content-Type: application/vnd.ms-excel

可以看出, 对text box和file upload box中的文件名所有浏览器均采取了相同的编码. 经证实, 是上传页面的编码方式——所有浏览器均对unicode数据(utf-8)采取了本地的编码方式(这里是ms932).

在服务器端对上传的数据进行解码.

解码的方式有很多, 这里我使用最普遍以及正规的request.setCharacterEncoding的方法. 发现form表单中的text box可以被正常解码, 但是file upload box中的文件名无法通过这种方式解码. 所以只能使用手工解码.

String fixedFileName = new String(fileName.getBytes("SJIS"), "UTF-8");

其中SJIS是客户端系统的编码, UTF-8是客户端页面的编码.

上传文件测试中, 所有浏览器表现一致, 需要注意的是文件名和表单数据的不同处理方式.

下载文件

使用一个unicode的JSP页面, 在页面上有一个固定的超链接, 传递给服务器一个文件名. 服务器依照这个文件名把服务器端的文件传递给客户端.

下载页面

<%@ page language="java" contentType="text/html; charset=utf-8"%>

<meta http-equiv="content-type" content="text/html; charset=utf-8">

<href="download.do?name=ああああ.xls">ダウンロード</a>

对于这样一个页面, 当点击超链接后, 各浏览器处理方式不同

IE会把超链接依照页面当前编码方式编码(这里是utf-8)后, 发送给服务器端

GET /nsupload/download.do?name=縺ゅ≠縺ゅ≠.xls HTTP/1.1

NC和FF会把超链接依照页面编码方式编码(这里是utf-8)后, 再通过url encoding后, 发送给服务器端

GET /nsupload/download.do?name=%E3%81%82%E3%81%82%E3%81%82%E3%81%82.xls HTTP/1.1

(经证实, E38182是「あ」的unicode代码)

在服务器收到提交的数据后, 需要对其进行解码. 需要注意的是这种方式下使用request.setCharacterEncoding无效. 所以必须手工解码.

name = new String(name.getBytes("ISO-8859-1"), "UTF-8");

其中ISO-8859-1是Tomcat服务器的特性, Tomcat会把所有的数据先转换为ISO-8859-1的形式. UTF-8是实际的编码方式.

在得到文件名后, 就可以正确地读取文件, 然后把文件传递给客户端了. 其中, 文件名是保存在Http报头(header)的Content-Disposition中.

response.setHeader("Content-Disposition""inline; filename=" + _filename);
//或者
response.setHeader("Content-Disposition""attachment; filename=" + _filename);

经实验证明, 使用inline或者attachment对文件名的编码方式没有影响.

另外一个需要设置的是Content-Type.

response.setContentType("application/vnd.ms-excel");
//或者
response.setContentType("application/vnd.ms-excel; charset=UTF-8");
//或者
response.setContentType("application/x-download; name=" + _filename);

经试验证明, 使用application/*的任何形式都对文件名的编码方式没有影响.
第二点, 经试验证明, 这里的charset设置会被三种浏览器忽略, 所以设置与否影响文件名的编码方式.
第三点, 经试验证明, 这里的name设置对文件名没有任何影响.

可能还有一个属性需要注意, 就是Content-Language. 经试验证明, Content-Language有无, 或者为何值, 对文件名没有任何影响.

那么对于non-ascii的文件名如何操作才可以保证客户端可以得到正确的显示呢?

经过调查, 有三种方法(在网上搜索后认为可能这篇文章是对于这个问题探讨最深入的文章)

第一, 使用URLEncoding方法. 即对文件名进行URLEncoding.

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


这种方式适用于IE, 但是不适用于NC和FF. 在这种方式下, 网络上传输的是url encoding后的ascii编码.

Content-Disposition: inline; filename=%E3%81%82%E3%81%82%E3%81%82%E3%81%82.xls

NC和FF不能对这样的文件名进行有效的解码.

NC download

FF download

第二, 使用字符串字符集强行转换为本地字符集方法, 这样做的原理是JVM底层全部为unicode. 所以一旦一个字符串表示了正确的字符集而被存储后, 这个字符串会被转换为任意字符集.

原理二是, IE和FF对非url encoding的non-ascii文件名采用客户端系统本地的编码方式进行转换.

name = new String(name.getBytes("Shift_JIS"), "ISO-8859-1");

需要注意的是, 这里的name原本是utf-8的.

在网络上传输的为

Content-Disposition: inline; filename=ああああ.xls


经过试验, IE和FF支持这种方式, NC不支持. 表现为NC无法解析文件名.

第三种, 使用Base64编码文件名. 原理是这种做法符合RFC2047的定义.

name = javax.mail.internet.MimeUtility.encodeText(name, "UTF-8""B");

使用到了JavaMail中的Base64编码的类MimeUtility.

在网络上传输的为经过Base64编码的ascii字符.

Content-Disposition: inline; filename==?UTF-8?B?44GC44GC44GC44GCLnhscw==?=

只有FF支持这种方式, IE表现为无法解析文件名, NC表现为忽略Base64编码.

NC base64 download

IE Base64 download

以上三种方法是目前来讲, 使浏览器可以正确下载non-ascii文件名的方法. 其中IE支持两种(url encoding和force transform), FF支持两种(force transform和base64 encoding), NC一种都不支持.

关于这次调查的结果, 对于NC多说两句, 我以为这个结果是由于NC 7.1和Tomcat 5.5不兼容造成的. Tomcat 5.5要求必须把所有报头先转变为ISO-8859-1的格式, 而NC 7.1却无法直接对ISO-8859-1进行正确的解析或者说是解析功能比较弱. 如果有时间, 我会继续验证非unicode的情况以及NC 8的情况.


---2006年9月14日21:00 补充---

在NC 8.1上进行了测试, 测试结果是NC 8.1支持方法三, 即base64 encoding.

nc81-base64-down.jpg

posted on 2006-09-14 20:43 Mongoose 阅读(5241) 评论(3)  编辑  收藏

<!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://www.blogjava.net/zamber/archive/2006/09/14/69752.html" dc:identifier="http://www.blogjava.net/zamber/archive/2006/09/14/69752.html" dc:title="Unicode网页中上传下载文件时发生文件名乱码的问题" trackback:ping="http://www.blogjava.net/zamber/services/trackbacks/69752.aspx" /> </rdf:RDF> -->

评论

一篇关于这个问题的thread. 作为memo记录在此, 虽然我的测试结果和thread上的结果不尽相同. —— 可能是浏览器版本和字符集的关系.
http://forum.java.sun.com/thread.jspa?threadID=696263  回复  更多评论   

# re: Unicode网页中上传下载文件时发生文件名乱码的问题 2006-09-25 15:11 Mongoose

我们经常在处理乱码问题的时候看到的都是"??", 为了能更有效地处理乱码问题, 有一个best practise就是打印一个字符串的byte code. 由于一个字符串在Java内部都是已Unicode存储, 所以打印的时候需要指定此字符串的encoding.
---
public static void printbyte(String str, String enc) throws Exception{
System.err.print("STR[" + str + "]-->[");
byte[] b = str.getBytes(enc);
for(int i = 0; i < b.length; i++) {
System.err.print(b[i]);
}
System.err.println("]" + enc);
}  回复  更多评论   

# re: Unicode网页中上传下载文件时发生文件名乱码的问题 2007-10-03 12:53 metal

这篇文章很棒!支持一下。  回复  更多评论   

<!--Beging Temp Save--># re: Unicode网页中上传下载文件时发生文件名乱码的问题 2006-09-14 20:48 Mongoose
分享到:
评论

相关推荐

    Linux下中文文件名乱码问题的详解 - CSDN博客1

    在Linux系统中,处理中文文件名时可能会遇到乱码的问题,这是因为Linux系统默认采用的字符编码与...通过以上步骤,可以有效地避免在Linux系统中遇到中文文件名乱码的情况,从而保证文件系统的正常操作和程序的兼容性。

    ASP.NET 解决下载文件名乱码问题

    在ASP.NET开发中,处理文件下载时经常遇到的一个问题是文件名乱码。这不仅影响用户体验,也降低了应用程序的专业性。本文将深入探讨如何在ASP.NET中解决下载文件名乱码的问题,通过分析代码示例,提供实用的解决方案...

    Java中压缩与解压--中文文件名乱码解决办法

    ### Java中压缩与解压——中文文件名乱码解决办法 #### 一、问题背景及原理分析 在Java中处理文件的压缩与解压时,经常会遇到中文文件名出现乱码的问题。这个问题主要源于Java中默认使用的编码方式与实际文件名...

    解决JMeter上传包含中文文件名乱码ApacheJMeter_http.jar

    总之,解决JMeter上传中文文件名乱码问题需要对JMeter的源代码有深入的理解,并能针对性地进行修改。通过确保正确处理文件名的编码,我们可以避免在测试过程中遇到的乱码困扰,从而提高测试的准确性和效率。

    文件下载response.setHeader()下载中文文件名乱码问题解决办法.pdf

    文件下载response.setHeader()下载中文文件名乱码问题解决办法 本文主要讨论了文件下载时response.setHeader()下载中文文件名乱码问题的解决办法。该问题是由于 HTTP 消息头中的 Content-Disposition 头字段不正确...

    welogic struts2文件下载中文件名乱码:在tomcat中是好的哦

    在IT领域,特别是Web开发中,处理文件下载时遇到文件名乱码问题是一个常见的挑战,尤其是在不同的服务器环境下,如WeLogic与Tomcat之间的差异。本文将深入探讨在WeLogic服务器中使用Struts2框架进行文件下载时遇到的...

    linux下的文件名乱码,转为正常

    下面将详细介绍如何在Linux下处理文件名乱码问题。 1. **字符编码基础** - **Unicode**:Unicode 是一种统一的字符编码标准,包含了世界上大部分文字系统,以数字的形式表示每个字符。 - **UTF-8**:UTF-8是...

    部署到linux服务器文件名乱码问题

    ### 部署到Linux服务器文件名乱码问题解析与解决 #### 一、问题背景与现象 在项目部署过程中,特别是在门户系统APP升级时,遇到了一个常见的问题:文件名乱码。具体表现为,在将文件从Linux服务器下载到Windows...

    ( response.setHeader()下载中文文件名乱码

    ( response.setHeader()下载中文文件名乱码问题

    Teleport Ultra 网页文件名乱码修复助手

    1.软件仅对Teleport Ultra 软件 下载网页中 “XX.html” 网页文件名中 “XX” 的乱码进行修复,此处XX为中文字符; 2.软件需要在WIN7及以上系统使用; 3.软件运行依托 .NET 4.5.1; 4.软件仅供技术交流使用,并未...

    HttpClient4.2.5上传文件,无中文文件名乱码问题

    HttpClient4.2.5实现文件上传,无中文文件名乱码问题。亲测无问题。有问题可吐槽!

    服务器下载word乱码解决方案(文件名乱码、内容乱码)

    往往开发环境和生产环境在环境部署时会遇到很多奇怪的问题,此次word文档下载就被卡住了,通过一番努力终于找到了原因,分享给大家。上传文件txt格式,内有方法详细的代码注释及原因说明,jar包比较常见,大家自行...

    ubuntu 下文件名乱码总结

    Ubuntu 文件名乱码解决方案总结 在 Ubuntu 系统中,文件名乱码是一个常见的问题,主要是由于编码问题引起的。以下是解决 Ubuntu 文件名乱码的总结,包括 GBK 乱码和 ASCII 乱码两种情况。 GBK 乱码 GBK 乱码的...

    zip库(解决文件名中文乱码问题).zip

    总之,"zip库(解决文件名中文乱码问题).zip" 是一个专门为C++开发的、修复了中文文件名乱码问题的ZIP操作库。它提供了方便的API接口,使得开发者能够在处理中文文件名时更加得心应手,避免了编码转换带来的困扰。...

    修改LinuxAS4挂载U盘文件名乱码

    ### 修改Linux AS4挂载U盘文件名乱码 在Linux AS4系统中,当用户尝试挂载含有中文或其他特殊字符的U盘时,可能会遇到文件名显示为乱码的问题。这种现象通常与系统的编码设置不符有关。本文将详细介绍如何解决这一...

    Java实现文件下载并解决中文文件名乱码

    ### Java实现文件下载并解决中文文件名乱码 在日常的Web开发中,经常会遇到需要让用户下载文件的需求,尤其是在企业级应用中。然而,在实际操作过程中可能会遇到一个常见问题:当文件名包含中文字符时,下载后的...

    java下载时文件名乱码

    在Java编程中,遇到“java下载时文件名乱码”的问题通常是由于编码不一致或处理不当造成的。在处理文件下载时,尤其是从Web服务器下载带有非ASCII字符的文件名时,这种问题尤为常见。让我们深入探讨这个问题,并提供...

    详解关于java文件下载文件名乱码问题解决方案

    Java文件下载文件名乱码问题解决方案 Java 文件下载文件名乱码问题是指在下载 Java 文件时,文件名出现乱码现象,影响下载文件的正确性。这种问题通常有两种情况:一是下载时中文文件名乱码,二是下载时因为路径中...

    JDK ZipEntry压缩中文文件名乱码解决

    项目中碰到问题.jdk zipEntry 压缩中文文件名乱码  上网查了下,有两种方法,一种修改jdk ZipInputStream及ZipOutputStream 的源文件,比较麻烦,不建议此项.  第二种 就是拿来主义,因为 开源项目 Ant 里已经有...

    jsp实现文件下载与中文文件名乱码问题解决

    本文将深入解析如何在JSP中实现文件下载,并解决中文文件名乱码的问题。 首先,我们需要了解HTTP协议在处理文件下载时的角色。当用户请求下载一个文件时,服务器需要设置响应头来指示浏览器如何处理这个响应。在JSP...

Global site tag (gtag.js) - Google Analytics