Java Applet - 无法将默认平台编码更改为其他编码

3

当我尝试上传一个文件名包含瑞典字符Ӧ Ӓ å时,我遇到了编码问题(我猜是这个原因)。在Windows上上传文件时,小程序工作得很好,但在Mac OS上却不行。

当我在服务器端打印文件名时,即Domino服务器上,它会变得混乱,并在Mac上显示方框。但是,当我通过new String(filename.getBytes("utf-8"))将编码设置为UTF-8时,Win和Mac上都显示?

更新:

以下是代码片段:

设置请求参数并发送:

...
request.setParameter("Name", tmpAtt.getFileName());
...

HttpURLConnection connection ...
connection.setRequestProperty("Content-Type", "multipart/form-data; charset=UTF-8; boundary=" + boundary);

if (os == null) os = connection.getOutputStream();

为文件名和输入流设置参数

request.setParameter(fileUploadFieldName, tmpAtt.getFilePath(), fi);

public void setParameter(String name, String filename, InputStream is) throws IOException {
    boundary();
    writeName(name);
    write("; charset=utf-8; filename=\"");
    write(filename);
    write('"');
    newline();
    write("Content-Type:");
    String type = connection.guessContentTypeFromName(filename);
    if (type == null) type = "application/octet-stream";
    writeln(type);
    newline();
    pipe(is, os);
    newline();
}

在向服务器发布结束时

public InputStream post() throws IOException {
    boundary();
    writeln("--");
    printOS(os);
    os.close();
    InputStream iis = connection.getInputStream();
    printIS(iis);
    return iis;
}

将字节写入 OutputStream 发送请求时,出现了这个输出。名字在我看来没问题。
------------------------------hxre3intl6yy-17eufpccwtxc89pbvyg0iwe3i
Content-Disposition: form-data; name="Name

Räpörå.log
------------------------------hxre3intl6yy-17eufpccwtxc89pbvyg0iwe3i
Content-Disposition: form-data; name="Name2


------------------------------hxre3intl6yy-17eufpccwtxc89pbvyg0iwe3i
Content-Disposition: form-data; name="APPROVALSTATUS

可能的问题有哪些呢?谢谢。
2个回答

2

Java字符串始终以UTF-16的形式进行内部编码,但这与您的问题无关,而尝试“设置编码”的字符串本质上是错误的。

编码用于在字符串和字节之间进行转换。您的问题在于,在执行此操作的某个点上,您未指定编码,因此Java使用平台默认编码。

由于文件系统API基于字符串,所以问题不能在该端出现,因此filename字符串可能在从用户检索它的点处损坏 - 或者因为有另一个实例错误地且毫无意义地尝试“设置编码”Java字符串。

eclipse中的编码设置仅适用于您的源代码或其他项目文件。


我尝试将其编码为 utf-8,但没有成功,在此之前我根本没有进行编码。文件名字符串的损坏似乎是合乎逻辑的,但当我在发布之前打印该值时,它看起来很好。 - Deam
@user330281:问题可能确实出在文件系统方面。尝试使用命令行参数 -Dfile.encoding=UTF8 运行该问题(在Eclipse运行配置中进行配置)。总的来说,似乎文件名中的非ASCII字符仍然存在问题。我最近注意到,在Windows PC和Linux NAS之间简单地复制文件时,非ASCII文件名会被损坏。 - Michael Borgwardt
抱歉,我忘记提到我正在浏览器中使用小程序,我想那么我就不需要在eclipse的运行配置中放置上述参数,对于浏览器中的小程序有什么解决方法?我应该通过将上述参数作为命令参数创建jar文件,还是将其作为<applet>标签中的参数?另一件事是我正在发送请求到Domino服务器,并希望它不会出现任何问题... 谢谢。 - Deam
@user330281:我认为你无法定义系统属性,但现在看起来你省略了设置中最重要的部分:你是否根本没有使用Java的文件系统API?如果文件是写入那个多米诺服务器的,那么很可能你遇到的问题就是在那里。 - Michael Borgwardt
但我不明白为什么当我从Windows上传这个奇怪命名的文件时它能够工作。我正在使用Java的FS API创建临时文件,至于文件名问题,我并没有使用它。我只是在请求(HttpRequest)中设置参数(filename),然后清除流以进行发布...看起来很简单,但它让我发疯了... - Deam
1
@user330281:啊,现在我们有所进展了。我猜测你在设置HttpRequest参数时可能会以平台默认编码方式结束,这就是为什么它取决于操作系统的原因。而且,要么你设置的方式有问题,要么Domino没有正确处理它。我建议你将代码的这部分添加到问题中。 - Michael Borgwardt

0

我刚刚将编码方案更改为ISO-8859-1

上述提到的write("Content-Type:");方法大致如下:

1. write(String s){
2. os.write(s.getBytes());
3. }

我刚把第二行改成了os.write(s.getBytes("ISO-8859-1"))

UTF-8不能工作,我不知道为什么???

方案在某个地方被更改为MacRoman,因为当我在这个(如上所述)行中添加了ISO-8859-1方案,即 request.setParameter("Name", new String(tmpAtt.getFileName().getBytes("ISO-8859-1")));之后,Name的末尾就变得混乱了。

但是我不明白为什么UTF-8无法使用,以及为什么方案在中间被更改???

谢谢


new String() 使用平台默认编码。正如我所说:试图将Java字符串转换为不同的编码是根本错误的。至于为什么UTF-8不起作用:文件名作为请求的HTTP头的一部分发送,而HTTP头隐含地使用ISO-8859-1,这是标准规定的。因此,您更改后的write()方法现在符合标准。 - Michael Borgwardt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接