Смарт-кавычки в MimeMessage не отображаются правильно в Outlook
-
22-08-2019 - |
Вопрос
Наше приложение берет текст из веб-формы и отправляет его по электронной почте соответствующему пользователю.Однако, когда кто-то копирует/вставляет печально известные «умные кавычки» или другие специальные символы из Word, все становится сложнее.
Пользователь вводит
он сказал мне «привет» — разве это не приятно?
Но когда сообщение появляется в Outlook 2003, оно выглядит следующим образом:
он поздоровался со мной, разве это не приятно?
Код для этого был:
Session session = Session.getInstance(props, new MailAuthenticator());
Message msg = new MimeMessage(session);
//removed setting to/from addresses to simplify
msg.setSubject(subject);
msg.setText(text);
msg.setHeader("X-Mailer", MailSender.class.getName());
msg.setSentDate(new Date());
Transport.send(msg);
После небольшого исследования я решил, что это, вероятно, проблема с кодировкой символов, и попытался перейти на UTF-8.Итак, я обновил код следующим образом:
Session session = Session.getInstance(props, new MailAuthenticator());
MimeMessage msg = new MimeMessage(session);
//removed setting to/from addresses to simplify
msg.setHeader("X-Mailer", MailSender.class.getName());
msg.addHeader("Content-Type", "text/plain");
msg.addHeader("charset", "UTF-8");
msg.setSentDate(new Date());
Transport.send(msg);
Это приблизило меня, но не сигару:
он сказал мне «привет» — разве это не приятно?
Не могу себе представить, что это необычная проблема. Что я пропустил?
Решение
Страница с вашей формой также использует UTF-8 или другую кодировку?Если вы не укажете кодировку веб-страницы, о формате данных, поступающих в ваш скрипт, можно только догадываться.
Редактировать:кодировка в сообщении должна быть установлена следующим образом:
msg.addHeader("Content-Type", "text/plain; charset=UTF-8");
поскольку набор символов — это не отдельный заголовок, а опция Content-type
Другие советы
Почему бы вам не заменить красивые цитаты обычными простыми цитатами?
Я бы проверил правильность получаемых от браузера данных - сбросил кодовые точки Юникода и сверил их с графики:
public static void printCodepoints(char[] s) {
for (int i = 0; i < s.length; i++) {
int codePoint = Character.isHighSurrogate(s[i]) ? Character
.toCodePoint(s[i], s[++i])
: s[i];
System.out.println(Integer.toHexString(codePoint));
}
}
Например, символ ДВОЙНАЯ ЛЕВАЯ КАВЫКА (“) — это символ U+201C.
Я давно не пользовался почтовым API, но MimeMessage.html.setText(текст, кодировка) метод, возможно, стоит посмотреть.Документация по setText (строка) говорит, что использует набор символов по умолчанию (вероятно, Windows-1252, если вы используете Windows с английским/латинским языком-1).
IIRC, кавычки MS Office встречаются в наборе символов «iso-8859-1».