【问题标题】:Is there a way to add aliases for Java's Charset names有没有办法为 Java 的字符集名称添加别名
【发布时间】:2025-12-10 22:25:02
【问题描述】:

我遇到了一个异常,隐藏在第 3 方库中,消息如下:

java.io.UnsupportedEncodingException: BIG-5

我认为这是因为 Java 没有为 java.nio.charset.Charset 定义这个名称。 Charset.forName("big5") 很好,但是 Charset.forName("big-5") 会抛出异常。 (所有这些名称似乎都不区分大小写。)

这与“utf-8”不同,后者有一些别名更宽容。例如,Charset.forName("utf8") 和 Charset.forName("utf-8") 都可以正常工作。

问题:有没有办法添加别名以便“big-5”映射到“big5”?

【问题讨论】:

  • 有没有第三方库JavaMail?
  • private static final Charset BIG5_CHARSET = Charset.forName("big5") 在某处创建一个常量?你没有问题了。还是您说这是您无法控制的内部代码?
  • 字符集名称从何而来?你能拦截和规范化它们吗?
  • @dnault 是的,它是 JavaMail。我也许可以截取数据,但如果我可以在全局某个地方定义别名会更容易。
  • 查看解决此问题的JavaMail FAQ entry,包括示例代码。 (来自Bill Shannon 对一个现已删除的答案的评论。)

标签: java character-encoding java-8 jakarta-mail


【解决方案1】:

你可以试试mail.mime.contenttypehandler系统属性:

在某些情况下,JavaMail 无法处理带有无效 Content-Type 标头的邮件。标头可能有不正确的语法或其他问题。此属性指定将用于在 JavaMail 使用它之前清理 Content-Type 标头值的类的名称。该类必须有一个具有此签名的方法: public static String cleanContentType(MimePart mp, String contentType) 每当 JavaMail 访问消息的 Content-Type 标头时,它会将值传递给该方法并使用返回的值。

一个例子是:

import java.util.Arrays;
import javax.mail.Session;
import javax.mail.internet.ContentType;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimePart;

public class FixEncodingName {

    public static void main(String[] args) throws Exception {
        MimeMessage msg = new MimeMessage((Session) null);
        msg.setText("test", "big-5");
        msg.saveChanges();
        System.out.println(msg.getContentType());
        System.out.println(Arrays.toString(msg.getHeader("Content-Type")));
    }

    public static String cleanContentType(MimePart p, String mimeType) {
        if (mimeType != null) {
            String newContentType = mimeType;
            try {
                ContentType ct = new ContentType(mimeType);
                String cs = ct.getParameter("charset");
                if ("big-5".equalsIgnoreCase(cs)) {
                    ct.setParameter("charset", "big5");
                    newContentType = ct.toString();
                }
            } catch (Exception ignore) {
                newContentType = newContentType.replace("big-5", "big5");
            }

            /*try { //Fix the header in the message.
                p.setContent(p.getContent(), newContentType);
                if (p instanceof Message) {
                    ((Message) p).saveChanges();
                }
            } catch (Exception ignore) {
            }*/
            return newContentType;
        }
        return mimeType;
    }
}

使用-Dmail.mime.contenttypehandler=FixEncodingName 运行时会输出:

text/plain; charset=big5
[text/plain; charset=big-5]

【讨论】:

    最近更新 更多