Java编码在Mac和一些Linux机器之间中断



我在本地开发机器和一台AWS Linux机器上遇到这个问题,UTF-8字符串被正确编码,但在另一台机器上它们被问号取代。这两个字符串起源于MIME电子邮件,并且都起源于一个共同的代码路径。正确编码和问号之间的差异既出现在stderr中,也出现在我们上传到AWS S3上的文件中。我在本地运行IntelliJ和,使用部署到损坏的Linux机器上的完全相同的jar。

所有机器上的Java版本都是一样的:

java版本"1.7.0_04"Java(TM) SE运行环境(build 1.7.0_04-b20)Java HotSpot(TM) 64位Server VM (build 23.0-b21, mixed mode)

我使用以下程序来验证默认字符集在任何地方都是相同的:

public class Test {
    public static void main(String[] args) {
        System.err.println(java.nio.charset.Charset.defaultCharset());    
    }
}

所有的方框都显示

utf - 8

我们将所有MIME字符串以字节形式保存在内存中,然后通过以下代码返回更高级别的代码作为UTF-8编码的字符串:

static final Charset charset = Charset.forName("UTF8");
// ...
return new String(bytes, ImapClient.charset);

然后通过InputStream mimeStream = IOUtils.toInputStream(mime)转化为InputStream,通过org.apache.james.mime4j.stream.MimeTokenStream解析。

当我们到达主题字段时,也就是无法正确编码的字段,我们使用

public static String decodeBodyText(String str) {
    try {
        return MimeUtility.decodeText(str);
    }
    catch (UnsupportedEncodingException exc) {
        // ignore
    }
    return str;
}

MimeUtility来自javax.mail.internet包。

这是在System.err.println呼叫中以不同的方式显示的主题。

是什么导致了这种不正确的编码?

缺少-Dmail.mime.charset=utf-8。由于某些原因,不同机器的默认值不同,但这个修复了它。

最新更新