当前位置: 首页 > 知识库问答 >
问题:

使用JavaMail阅读电子邮件内容时的编码问题

翁文康
2023-03-14

我正在使用JavaMail 1.4.1(我已经升级到1.4.5版本,但有同样的问题)从一个电子邮件帐户读取消息,但我在内容编码方面有问题:

POP3Message pop3message;
... 
Object contentObject = pop3message.getContent();
...   
String contentType = pop3message.getContentType();
String content = contentObject.toString();

一些消息被正确读取,但其他消息由于编码不合适而具有奇怪的字符。我意识到它不适用于特定的内容类型。

如果content entType是以下任何一个,它都能很好地工作:

>

  • 文本/普通;charset=ISO-8859-1


    charset="iso-8859-1"

    文本/纯文本
    charset=“ISO-8859-1”
    format=“flowed”

    文本/纯文本;字符集=windows-1252

    但如果是的话就不会了:

    • 文本/纯文本
      charset=“utf-8”

    对于这个内容类型(UTF-8一个)如果我试图得到编码(pop3message.get编码())我得到

    引用可打印

    例如,对于后一种编码,我在调试器中得到字符串值(与我在持久化对象后在数据库中看到的方式相同):

    UbicaciÃn(代替Ubicación)

    但是,如果我在浏览器中使用电子邮件客户端打开电子邮件,它可以被毫无问题地读取,而且是一条普通的消息(没有附件,只有文本),因此消息似乎没有问题。

    你知道怎么解决这个问题吗?

    谢谢

    UPDATE这是我添加的一段代码,用来尝试jlordo给出的getUTF8Content()函数

    POP3Message pop3message = (POP3Message) message;
    String uid = pop3folder.getUID(message);
    
    //START JUST FOR TESTING PURPOSES
    if(uid.trim().equals("1401")){
        Object utfContent = pop3message.getContent();
        System.out.println(utfContent.getClass().getName()); // it is of type String
        //System.out.println(utfContent); // if not commmented it prints the content of one of the emails I'm having problems with.
        System.out.println(pop3message.getEncoding()); //prints: quoted-printable
        System.out.println(pop3message.getContentType()); //prints: text/plain; charset="utf-8"
        String utfContentString = getUTF8Content(utfContent); // throws java.lang.ClassCastException: java.lang.String cannot be cast to javax.mail.util.SharedByteArrayInputStream
        System.out.println(utfContentString);
    }
    
    //END TEST CODE
    
  • 共有3个答案

    丁沛
    2023-03-14

    对我有用的是,我调用了getContentType(),检查字符串中是否包含“utf”(定义用作utf之一的字符集)。

    如果是,在这种情况下,我会以不同的方式对待内容。

    private String encodeCorrectly(InputStream is) {
        java.util.Scanner s = new java.util.Scanner(is, StandardCharsets.UTF_8.toString()).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";
    }
    

    (从SO上的答案中修改IS到String转换器)

    这里的重要部分是使用正确的Charset。这为我解决了这个问题。

    夹谷硕
    2023-03-14

    试试这个,让我知道它是否有效:

    if ( *check if utf 8 here* ) {
        content = getUTF8Content(contentObject);
    }
    
    // TODO take care of UnsupportedEncodingException, 
    // IOException and ClassCastException
    public static String getUTF8Content(Object contentObject) {
        // possible ClassCastException
        SharedByteArrayInputStream sbais = (SharedByteArrayInputStream) contentObject;
        // possible UnsupportedEncodingException
        InputStreamReader isr = new InputStreamReader(sbais, Charset.forName("UTF-8"));
        int charsRead = 0;
        StringBuilder content = new StringBuilder();
        int bufferSize = 1024;
        char[] buffer = new char[bufferSize];
        // possible IOException
        while ((charsRead = isr.read(buffer)) != -1) {
            content.append(Arrays.copyOf(buffer, charsRead));
        }
        return content.toString();
    }
    

    顺便说一句,JavaMail 1.4.1是一个要求吗?最新版本是1.4.5。

    林鸿飞
    2023-03-14

    你是如何发现这些信息有“奇怪的字符”的?您是否在某处显示数据?无论使用何种方法来显示数据,都有可能无法正确处理Unicode字符。

    第一步是确定问题是得到了错误的字符,还是正确的字符显示不正确。您可以检查数据中每个字符的Unicode值(例如,从getContent方法返回的字符串中),以确保每个字符都有正确的Unicode值。如果是这样,问题在于您用来显示字符的方法。

     类似资料:
    • 问题内容: 我正在使用javamail,但无法从Gmail电子邮件中获取HTML。我有以下内容: 上面所有方法都可以,但是我无法打印或获取实际的HTML或文本电子邮件。我只是得到某种InputStream,如何轻松处理以获得原始的电子邮件HTML? 我也尝试遍历消息,但这并没有使我走得太远: } 谢谢大家的帮助。 问题答案: 该对象包含电子邮件的正文。您需要阅读整个流,才能阅读整个消息。例如,该S

    • 问题:是否有人从SMTP服务器通过JavaMail成功地向hotmail帐户发送电子邮件?如果是这样的话,你能提出有效的代码吗? 我可以使用我的JavaMail代码向gmail和yahoo帐户发送电子邮件,但我不能向hotmail帐户发送任何电子邮件。如果我使用手机或其他电子邮件客户端,并使用与JavaMail代码相同的SMTP服务器,那么我确实可以向hotmail帐户发送电子邮件。这让我相信Ja

    • 我有一些Java代码,它发送一封电子邮件,代码类似如下:实际上,我从Httprequest param获得了Mimemessage,在该Mimemessage中,我将在现有的主体中附加一些内容。 如果消息是text/plain和text/html content-type,我设置的content-transfer编码就不适用于body。 基于此文档 问:尽管JavaMail为我完成了所有的编码和解

    • 问题内容: 现在我在这里 一些字母带有base64编码。怎么解码呢? base64.b64encode(some_string)-没有帮助 问题答案: **我没有写这个取自https://yuji.wordpress.com/2011/06/22/python-imaplib-imap-example- with-gmail/

    • 问题内容: 我正在尝试在JavaMail API的帮助下通过IMAP访问来自Gmail帐户的电子邮件。我想知道为什么代码对一个电子邮件帐户有效,而对另一个电子邮件帐户无效。 我可以访问两个电子邮件帐户的文件夹。但是对于其中一个电子邮件帐户,无法访问其他文件夹,例如,它将引发异常。有人可以解释出什么问题了吗? 先感谢您。 这是代码: 问题答案: 是否有一个帐户使用非英语用户界面? Gmail文件夹名

    • 目前,我的代码使用IMAP(imaps)和JavaMail访问我的Gmail收件箱,目的是阅读从最新到最旧发送给我自己的电子邮件,识别哪些电子邮件具有. zip或. xap格式的附件。如果找到,电子邮件的主题会显示出来,并询问我是否要下载附件。 如果我单击否,它会继续搜索。如果我单击是,它会调用createFolder方法来创建一个目录,将附件保存在那里,然后提取它。 问题:我收件箱中最近的一封电