JavaMail - Attachment filename not displaying UTF-8 characters correctly - java

I am trying to send mails that may contain UTF-8 characters in subject, message body and in the attachment file name.
I am able to send UTF-8 characters as a part of Subject as well as Mesage body. However when I am sending an attachment having UTF-8 characters as a attachment file name, it is not displaying it correctly.
So my question is how can I set attachement filename as UTF-8?
Here is part of my code:
MimeBodyPart pdfPart = new MimeBodyPart();
pdfPart.setDataHandler(new DataHandler(ds));
pdfPart.setFileName(filename);
mimeMultipart.addBodyPart(pdfPart);
Later edit:
I replaced
pdfPart.setFileName(filename);
with
pdfPart.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
and it is working perfectly.
Thanks all.

MIME Headers (like Subject or Content-Disposition) must be mime-encoded, if they contain non-ascii chars.
Encoding is either "quoted printable" or "base64". I recommend for quoted-printable.
See here: Java: Encode String in quoted-printable

I don't know how you send attachments. If upload through tomcat server, It could cause by value of URIEncoding in conf/server.xml

Related

How convert mail body from iso-8859-2 into utf-8

I'm using JavaMail to handle mail from my mailbox, and I have a following problem.
The content type of a mail is: Content-Type: text/plain; charset=iso-8859-2 (that's only in this case, I have to handle various mails with cp-1250 and many others).
And to get the body of this mail I'm using:
mimeMessage.getContent().toString()
and the content of the mail is returned but is not converted into utf-8, it's still in iso-8859-2 with causes generate text:
w ďż˝omďż˝y. instead of w Łomży.
How can I handle bodies with different than utf-8 encoding to convert it to utf? Is there any possibility to make it in JavaMail, that means JavaMail can convert an mail body from defined charset into utf-8?

Set "mail.strictly_mime.parm_folding" in javamail

I'do use javamail to send mail with long filename attachments. The javamail acts accordingly to more recent RFC, and span the filename in two lines of the mail's header, like this example:
------=_Part_0_978693914.1433356404377
Content-Disposition: ATTACHMENT;
filename*0="=?UTF-8?Q?arquivo_com_nome_grande_e_acentua=C3=A7=C3=A3o.png\"; f";
filename*1="ilename*1=\"?="
Content-Type: APPLICATION/OCTET-STREAM;
name*0="=?UTF-8?Q?arquivo_com_nome_grande_e_acentua=C3=A7=C3=A3o.png\"; n";
name*1="ame*1=\"?="
Content-Transfer-Encoding: BASE64
Mail clients like Outlook don't understand it, so I need to make javamail don;t split the filename in two lines.
Reading the RFC, I found an attribute that says to don't split:
"mail.strictly_mime.parm_folding"
How do I set it in javamail?
The mail.strictly_mime.parm_folding property is for Thunderbird, it's not in the RFC.
According to this Thunderbird article, Outlook doesn't support RFC 2231, which JavaMail is using to encode the filename parameter. You can disable RFC 2231 encoding by setting the JavaMail System property "mail.mime.encodeparameters" to "false". You'll probably want to set the System property "mail.mime.encodefilename" to "true" to use the non-standard filename encoding that Outlook supports.
I found this problem on Wildfly Server V.10.x
Solving by insert format="flowed" into Content Type
MimeBodyPart part = new MimeBodyPart();
part.addHeader("Content-Type", "application/pdf; charset=\"UTF-8\"; format=\"flowed\" ");
part.setFileName(MimeUtility.encodeText(file.getName(), "UTF-8", null));
//setDataHandler

How to upload file with non-ASCII filename using REST-service?

I create Java 7 REST service using Spring, Apache CXF.
public SuccessfulResponse uploadFile(#Multipart("report") Attachment attachment)
I use "Content-Disposition" parameter in order to retrieve file name. I've read some solutions which are usedfor downloading files (for example, url-encoding). But how to cope with non-ASCII filenames for upload? Is it a client-side or a server-side solution? The signature of the method above can be changed. The client side uses html5 file api + iframe.
My experience is that content-disposition doesn't handle UTF8 in general. You can simply add another multipart field for the filename - multipart fields support charset indication and handles UTF8 chars if done correctly.
You can use the UTF8 for a filename (according to https://www.rfc-editor.org/rfc/rfc6266 and https://www.rfc-editor.org/rfc/rfc5987). For the Spring the easiest way is to use org.springframework.http.ContentDisposition class. For example:
ContentDisposition disposition = ContentDisposition
.builder("attachment")
.filename("репорт.export", StandardCharsets.UTF_8)
.build();
return ResponseEntity
.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, disposition.toString())
.body((out) -> messageService.exportMessages(out));
It is an example to send the file from the server (download). To upload the file you can follow the same RFC, even the Content-Disposition header must be prepared on the browser, by JavaScript for example, and looks like:
Content-Disposition: attachment;
filename="EURO rates";
filename*=utf-8''%e2%82%ac%20rates
Parameter filename is optional in this case and is a fallback for the systems that don't support the RFC 6266 (it contains the ASCII file name). Value for filename* must the URL Encoded (https://www.url-encode-decode.com).

Chinese lettes not read properly using Java Mail API

I am having an email listener which reads mail from gmail. When I send a mail from Outlook client which contains chinese character, the encoding is set to gb2312, which causes improper result in part.getContent() in Java mail api .
If encoding from client is set to Chinese Big5 program works properly but we can't change the encoding in Outlook Client . Is there a way to read from Java Mail API but setting the content type or any alternate approach to get the proper content??????
https://community.oracle.com/message/5440489#5440489
Used GBK charset to read the file for all GB2312 file since gb2312 is a subset of GBK.
The following then should work with a bit of luck:
String content = mail. ...
// The bytes as sent, and then interpreted as gb2312:
byte[] bytes = content.getBytes("gb2312");
// Now correctly interprete the bytes as Big5:
content = new String(bytes, "Big5");

Properly set encoding to UTF-8, even then email come up with ? and �

I am using javax.mail API for sending email to my Outlook. There are chinese and french characters in my Body.
I am properly setting body as
MimeMessage.setText(body, "UTF-8");
Also in the email I am checking the Headers. They are properly coming as :
Content-type: text/plain;
charset="UTF-8"
Content-transfer-encoding: quoted-printable
The funny thing is that from the Other Machine, the email is coming up fine, but when I try it from my desktop, It doesn't encode properly.
I am also checking logs by printing the body. They are properly coming up in chinese and french.
Help needed ?
Does it is anything to do with Sendmail??
Should have worked; you only forgot to do the subject too. Especially as you checked the header. Encoding calls:
MimeMessage message = new MimeMessage(session);
message.setSubject(subject, "UTF-8");
message.setText(body, "UTF-8");
//message.setHeader("Content-Type", "text/plain; charset=UTF-8");
I think, your email settings on the desktop force the wrong encoding.
Paranoia: Check the body string, via a hard-coded u-escaped string:
message.setText("\u00e9\u00f4\u5837" + body, "UTF-8"); // éô堷

Categories