I use this code to send messages to users via the mail.ru server:

package com.art.func; import com.art.config.AppSecurityConfig; import com.art.model.Users; import com.art.model.supporting.GenericResponse; import com.art.model.supporting.SendingMail; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.web.multipart.MultipartFile; import javax.mail.Authenticator; import javax.mail.MessagingException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeUtility; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Properties; @org.springframework.stereotype.Service public class PersonalMailService { private static final String ENCODING = StandardCharsets.UTF_8.name(); public GenericResponse sendEmails(Users user, SendingMail sendingMail, String username, String pwd, String who, List<MultipartFile> file){ GenericResponse response = new GenericResponse(); JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); String fileName = "mail.ru.properties"; Properties prop = new Properties(); InputStream input; try{ input = AppSecurityConfig.class.getClassLoader().getResourceAsStream(fileName); prop.load(input); }catch (IOException ex){ ex.printStackTrace(); } //Using mail.ru mailSender.setHost(prop.getProperty("mail.host")); mailSender.setPort(Integer.parseInt(prop.getProperty("mail.port"))); mailSender.setUsername(username); mailSender.setPassword(pwd); mailSender.setProtocol(prop.getProperty("mail.protocol")); Authenticator auth = new MyAuthenticator(mailSender.getUsername(), mailSender.getPassword()); /* НОВОЕ */ System.setProperty("mail.mime.encodefilename", "true"); System.setProperty("mail.mime.encodeparameters", "false"); /* НОВОЕ */ Properties javaMailProperties = new Properties(); javaMailProperties.put("mail.transport.protocol", prop.getProperty("mail.protocol")); javaMailProperties.put("mail.smtp.port", Integer.parseInt(prop.getProperty("mail.port"))); javaMailProperties.put("mail.smtp.host", prop.getProperty("mail.host")); javaMailProperties.put("mail.smtp.auth", prop.getProperty("mail.smtp.auth")); javaMailProperties.put("mail.debug", prop.getProperty("mail.debug")); javaMailProperties.put("mail.smtp.starttls.enable", prop.getProperty("mail.smtp.starttls.enable")); javaMailProperties.put("mail.mime.charset", ENCODING); Session session = Session.getInstance(javaMailProperties, auth); mailSender.setJavaMailProperties(javaMailProperties); mailSender.setSession(session); mailSender.send(mimeMessage -> { MimeMessageHelper messageHelper = new MimeMessageHelper( mimeMessage, true, StandardCharsets.UTF_8.name()); messageHelper.setTo(user.getEmail()); messageHelper.setSubject(sendingMail.getSubject()); messageHelper.setText(sendingMail.getBody()); messageHelper.setFrom(new InternetAddress(username, who)); file.forEach(f -> { String attachName = f.getOriginalFilename(); if (!attachName.equals("")) { try{ messageHelper.addAttachment(MimeUtility.encodeText(attachName, StandardCharsets .UTF_8.name(), "B"), f); response.setMessage("Письма успешно отправлены."); } catch (MessagingException e) { response.setError("При отправке писем что-то пошло не так."); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }); }); return response; } class MyAuthenticator extends Authenticator { private String user; private String password; MyAuthenticator(String user, String password) { this.user = user; this.password = password; } public PasswordAuthentication getPasswordAuthentication() { String user = this.user; String password = this.password; return new PasswordAuthentication(user, password); } } 

The subject of the letter and the content comes in the correct encoding. The problem is that if I send an email with an attachment of files (names in Russian) to a mail.ru user, the file comes in with the correct name (in Russian). If I send to gmail.com, then there are 2 options. 1. If you browse in the browser, then the warped name comes "= _UTF-8_B_0JrQsNC70YpcpHg00LvRj9GC0L7RgCDQtNC 0YXQvtC00L0 = _ = = _UTF-8_B_0L7RgdGC0Lgg0L3QsCMAHMHM_GFVTC00L0 = _ = = _UTF-8_B_0L7RgdGC0Lgg0L3QsCMAHMHC_LQRtC00L0 = _ = = _UTF-8_B_0L7RgdGC0Lgg0L3QsNCAAAAAA = 2. If I look through the iPhone (standard mail application), then everything is displayed correctly. I do not know where to dig. 3 days treading water.

UPD:

The error appears if the length of the file name is more than 33 characters (including "dot" and extension). Still do not understand where to look. Reducing the length of names is not an option. Ideas?

  • one
    I can push it off and play around with the properties as indicated by the link like this: System.setProperty("mail.mime.encodeparameters", "false"); (specify at the beginning of the method) - MrFylypenko
  • @MrFylypenko, thanks! The second time you give the right direction, thanks to which my questions are solved! Issue as a separate answer so that I can mark it as resolved. In the code of the first post, you can see the added lines that solved the problem. - Alexander Stegnin

1 answer 1

Decisions taken from here .

MIME spec speaks of a coded word: A coded word can contain up to 75 characters, including charset, encoding, encoded text, and delimiters. If you need to encode more text than will be placed in a 75-character coded word, several coded words (separated by the CRLF space) can be used.

Those. The default file name is encoded according to the MIME specification and is not supported by all mail programs.

To use non-standard MIME encoding for file names, you must set the system properties "mail.mime.encodefilename" to "true" and "mail.mime.encodeparameters" to "false". In the code it will look like this:

 System.setProperty("mail.mime.encodefilename", "true"); System.setProperty("mail.mime.encodeparameters", "false");