Jakarta mail javamail抛出java.io.UnsupportedEncodingException:unknown-8bit

Jakarta mail javamail抛出java.io.UnsupportedEncodingException:unknown-8bit,jakarta-mail,Jakarta Mail,我尝试使用javamail lib阅读一些电子邮件。当电子邮件包含MIME头(内容类型:text/plain;charset=“unknown-8bit”)时,我收到以下错误:java.io.UnsupportedEncodingException:unknown-8bit 知道为什么会发生这种情况吗?因为“unknown-8bit”不是已知的字符集名称。这在中进行了解释,以及处理此问题的备选方案。我在这里复制了答案,但请注意,这可能会过时。请务必在JavaMail常见问题解答中搜索您可能遇到的

我尝试使用
javamail lib
阅读一些电子邮件。当电子邮件包含MIME头
(内容类型:text/plain;charset=“unknown-8bit”)
时,我收到以下错误:
java.io.UnsupportedEncodingException:unknown-8bit

知道为什么会发生这种情况吗?

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

Q:为什么在对包含文本数据的bodypart调用getContent()时会出现UnsupportedEncodingException

A:文本正文部分(即类型为“text/plain”、“text/html”或“text/xml”的正文部分)在使用getContent()时返回Unicode字符串对象。通常,此类BodyPart在内部将其文本数据保存在一些非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
    }
}
JDK还不支持一些常用的字符集。您可以在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
==>UnknownCharsetProvider.java META-INF/services/java.nio.charset.spi.CharsetProvider,因为“unknown-8bit”不是已知的字符集名称。这在中进行了解释,以及处理此问题的备选方案。我在这里复制了答案,但请注意,这可能会过时。请务必在JavaMail常见问题解答中搜索您可能遇到的任何其他JavaMail问题

Q:为什么在对包含文本数据的bodypart调用getContent()时会出现UnsupportedEncodingException

A:文本正文部分(即类型为“text/plain”、“text/html”或“text/xml”的正文部分)在使用getContent()时返回Unicode字符串对象。通常,此类BodyPart在内部将其文本数据保存在一些非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
    }
}
JDK还不支持一些常用的字符集。您可以在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

==>UnknownCharsetProvider.java META-INF/services/java.nio.charset.spi.CharsetProvider因为那不是真正的编码?因为那不是真正的编码?