MimeMessage のスマート引用符が Outlook で正しく表示されない
-
22-08-2019 - |
質問
私たちのアプリケーションは Web フォームからテキストを取得し、それを電子メール経由で適切なユーザーに送信します。ただし、誰かが 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、または異なる文字セットを使用してページのですか?あなたがWebページの文字セットを指定しない場合、スクリプトに来るデータの形式は、誰の推測です。
<時間>編集:メッセージのcharsetは次のように設定する必要があります:
msg.addHeader("Content-Type", "text/plain; charset=UTF-8");
文字セットが別のヘッダーはないので、しかし、コンテンツタイプのオプション
他のヒント
素敵な引用を通常のプライム引用に置き換えてみませんか?
ブラウザから受信したデータが正しいことを確認します。Unicode コードポイントをダンプし、それらを チャート:
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));
}
}
たとえば、記号 DOUBLE LEFT QUOTATION MARK (“) は文字 U+201C です。
久しぶりにメールAPIを使いましたが、 MimeMessage.html.setText(テキスト, 文字セット) 方法は検討してみる価値があるかもしれません。に関するドキュメント setText(文字列) デフォルトの文字セット (英語/Latin-1 Windows を使用している場合は、おそらく Windows-1252) を使用すると述べています。
IIRC、MS Officeの引用符はキャラクタ "ISO-8859-1" を発見されます。