javamail 抛出 java.io.UnsupportedEncodingException:未知-8位

Sat*_*mar 0 jakarta-mail

我尝试使用 来阅读一些电子邮件javamail lib。当电子邮件包含 MIME 标头时(Content-Type: text/plain; charset="unknown-8bit"),我收到此错误:java.io.UnsupportedEncodingException: unknown-8bit

有什么想法为什么会发生这种情况吗?

Bil*_*non 5

因为“unknown-8bit”不是已知的字符集名称。JavaMail FAQ对此进行了解释,并提供了处理此问题的替代方法。我已将答案复制到此处,但请注意,这可能会过时。请务必在 JavaMail 常见问题解答中搜索您可能遇到的任何其他 JavaMail 问题。

问:当我对包含文本数据的正文部分调用 getContent() 时,为什么会收到 UnsupportedEncodingException?

答:当使用 getContent() 时,文本正文部分(即类型为“text/plain”、“text/html”或“text/xml”的正文部分)返回 Unicode String 对象。通常,此类正文部分在内部以某种非 Unicode 字符集保存其文本数据。JavaMail(通过相应的 DataContentHandler)尝试将该数据转换为 Unicode 字符串。底层 JDK 的字符集转换器用于执行此操作。如果 JDK 不支持特定的字符集,则会抛出 UnsupportedEncodingException。在这种情况下,您可以使用 getInputStream() 方法以字节流形式检索内容。例如:

String s;
if (part.isMimeType("text/plain")) {
    try {
        s = part.getContent();
    } catch (UnsupportedEncodingException uex) {
        InputStream is = part.getInputStream();
        /*
         * Read the input stream into a byte array.
         * Choose a charset in some heuristic manner, use
         * that charset in the java.lang.String constructor
         * to convert the byte array into a String.
         */
         s = convert_to_string(is);
    } catch (Exception ex) {
        // Handle other exceptions appropriately
    }
}
Run Code Online (Sandbox Code Playgroud)

有一些常用的字符集 JDK 尚不支持。您可以在http://www.freeutils.net/source/jcharset/的 JCharset 包中找到对其中一些附加字符集的支持。

您还可以为 JDK 已支持的现有字符集添加别名,以便通过附加名称来识别它。您可以为“坏”字符集名称创建一个字符集提供程序,该名称仅重定向到现有的字符集提供程序;请参阅以下代码。创建适当的 CharsetProvider 子类并将其与 META-INF/services 文件一起包含,JDK 将找到它。显然,您可以变得更加聪明,例如将所有未知字符集重定向到“us-ascii”。

==> UnknownCharsetProvider.java <==
import java.nio.charset.*;
import java.nio.charset.spi.*;
import java.util.*;

public class UnknownCharsetProvider extends CharsetProvider {
     private static final String badCharset = "x-unknown";
     private static final String goodCharset = "iso-8859-1";

     public Charset charsetForName(String charset) {
         if (charset.equalsIgnoreCase(badCharset))
             return Charset.forName(goodCharset);
         return null;
     }

     public Iterator<Charset> charsets() {
         return Collections.emptyIterator();
     }
}

==> META-INF/services/java.nio.charset.spi.CharsetProvider <==
UnknownCharsetProvider
Run Code Online (Sandbox Code Playgroud)