附件名称编码失败

4

我尝试发送一封带有附件(PDF文件)的电子邮件,但接收者收到的文件名称不同,并且没有.pdf结尾。该文件名称为希腊语。

try {
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress("from@mail.com"));
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mail));
    message.setSubject(title,"utf-8");

    // Create the message part
    BodyPart messageBodyPart = new MimeBodyPart();

    // Now set the actual message
    messageBodyPart.setText("This is message body");

    // Create a multipar message
    Multipart multipart = new MimeMultipart();

    // Set text message part
    multipart.addBodyPart(messageBodyPart);

    // Part two is attachment
    messageBodyPart = new MimeBodyPart();

    String filename = "file.pdf";
    String f = name + " Πρόγραμμα Ιανουάριος 2016.pdf";  // the desired name of the file
    DataSource source = new FileDataSource(filename);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(MimeUtility.encodeText(f, "UTF-8", null));
    multipart.addBodyPart(messageBodyPart);

    // Send the complete message parts
    message.setContent(multipart);

    Transport.send(message);

    System.out.println("Mail " + mail +" sent");
} catch (MessagingException e) {
    throw new RuntimeException(e);
}

name是一个字符串变量,之前已经赋值。奇怪的是,如果我有String f = name + " αααα.pdf",接收方会成功地得到一个名为Ρουβάς αααα.pdf的pdf文件,但是如果我有这个字符串f = name + " Πρόγραμμα Ιανουάριος 2016.pdf";他就不行了。他得到的东西类似于=_UTF-8_B_zpzOtc Dz4POsc67zrHPgiDOmc6xzr3Ov8 FzqzPgc65zr_Pgi___ ___filename_1=__5wZGY=_=

我添加了message.writeTo(System.out);,并得到了:

MIME-Version: 1.0
Content-Type: multipart/mixed; 
    bou

    ndary="----=_Part_0_1825884453.1457025565509"

    ------=_Part_0_1825884453.1457025565509
    Content-Type: text/plain; charset=us-ascii
    Content-Transfer-Encoding: 7bit

    This is message body
    ------=_Part_0_1825884453.1457025565509
    Content-Type: application/octet-stream; 
        name*0="=?UTF-8?B?zpzOtc+Dz4POsc67zrHPgiDOmc6xzr3Ov8+FzrHPgc6vzr/Pgi"; 
        name*1="Ay?=
     =?UTF-8?B?MDE2zpnOsc69zr/Phc6sz4HOuc6/z4IgMjAxNi5wZGY=?"; 
        name*2="="
    Content-Transfer-Encoding: base64
    Content-Disposition: attachment; 
        filename*0="=?UTF-8?B?zpzOtc+Dz4POsc67zrHPgiDOmc6xzr3Ov8+FzrHPgc6vzr/Pgi"; 
        filename*1="Ay?=
     =?UTF-8?B?MDE2zpnOsc69zr/Phc6sz4HOuc6/z4IgMjAxNi5wZGY=?"; 
        filename*2="="

使用 props.setProperty("mail.mime.encodeparameters", "false");true

MIME-Version: 1.0
Content-Type: multipart/mixed; 
    boundary="----=_Part_0_797681969.1457074816557"

------=_Part_0_797681969.1457074816557
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

This is message body
------=_Part_0_797681969.1457074816557
Content-Type: application/octet-stream; name="?????????? 2016.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; 
    filename*=Cp1252''%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%202016.pdf

当您调用setFileName时,JavaMail应该会为您明确编码文件名,因此您不需要显式地进行编码。您使用的是哪个版本的JavaMail?如果在Transport.send之前添加message.writeTo(System.out);,那么消息头看起来像什么?用于读取和显示接收到的消息的是哪个程序? - Bill Shannon
我使用的是JavaMail 1.5.5。接收者得到的文件没有文件扩展名,所以如果你添加.pdf,你将可以正常打开它。 - yaylitzis
我将 message.writeTo(System.out); 的输出添加到了 @BillShannon 的问题中。 - yaylitzis
如果您拥有MimeMessageHelper实例,您可以添加“mimeMessageHelper.setEncodeFilenames(false)”来帮助。 - D. Naumovich
1个回答

6
因为您自己对文件名进行编码,所以使用的是非标准的MIME编码格式,如JavaMail FAQ中所述。然后,将这个非标准编码的文本使用标准RFC 2231技术拆分成多个参数。这种混合使用非标准和标准格式可能会导致邮件阅读器混淆。
尝试让JavaMail为您进行编码,删除对的调用。如果不起作用,请将系统属性设置为以禁用RFC 2231编码。

1
我移除了 MimeUtility.encodeText,并且有所改善,我收到了一个名为 ????? ???? ???? ???.pdf 的 PDF 文件。然后我添加了:props.setProperty("mail.mime.encodeparameters", "false");true,但是我仍然得到了 ????????.pdf。 - yaylitzis
我在问题中添加了 message.writeTo(System.out); 的结果。 - yaylitzis
看起来你的默认字符集不适合文件名中的字符。尝试将系统属性mail.mime.charset设置为“utf-8”。 - Bill Shannon
2
@yaylitzis 属性 mail.mime.encodeparameters 是一个系统属性,因此您应该写成 System.setProperty("mail.mime.encodeparameters", "false"); - Bill Tsagkas
嗨@BillShannon,我遇到了相同的问题,但是在解码方面。我的输入文件在有效负载中具有filename0="Post Discharge Follow-Up Call Script doc$454c0369-1283-4446-a07d"; filename1=-cdc4cb175da8.pdf,当我进行以下解析时,它会从解析对象中删除filename*1。请问您能否提供解决方法。这是我的解析代码:MimeMessage message=new MimeMessage(IncomingMessage.getMessage()); MimeMessageParser parser = new MimeMessageParser(message); parser.parse(); 当我这样做并尝试获取附件-> getfilename时,它会给出空文件名。 - Aakash Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接