Java ベースの Spring Integration 駆動の電子メール アダプターを含む Grails アプリがあります。電子メール アダプタは、単一のソースからの電子メールを処理し、ビジネス ルールに基づいて、電子メールの HTML 本文CLOB
を参照用に Oracle に追加するなど、いくつかの内部テーブルを更新することにより、特定の通信をユーザーに報告します。
約半分の確率で、HTML 内のリンクは、CLOB に追加されるときに破損します。たとえば、" =df " は Unicode U+00DFとして解釈され、" ß " (LATIN SMALL LETTER SHARP S) に変換され、" =20 " はスペースに変換されます。これらの予期しないマッピングは両方ともリンクを壊します。
http://www.mycompany.com/MyProject/MyApp.xxx?field1=dfa1.0&field2=2.0&field3=20012345&field4=N
http://www.mycompany.com/MyProject/MyApp.xxx?field1ßa1.0&field2=2.0&field3 012345&field4=N
この破損は常に発生するわけではなく、発生するパターンを特定できませんでした。
これは、電子メールの HTML の内容に「触れる」唯一のコードです...
public void processMessage(Message<?> message) {
if (message.getPayload() instanceof MimeMessage) {
MimeMessage mimeMessage = (MimeMessage) message.getPayload();
try {
String subject = mimeMessage.getSubject();
logger.info("Subject : " + subject);
// Get the main body of the message -- Assumes the email is in HTML format and
// uses that to isolate the interesting bits of the email to analyze
String content = convertStreamToString(MimeUtility.decode(mimeMessage.getDataHandler().getDataSource().getInputStream(), "quoted-printable"));
logger.info("Content Length (bytes) : " + content.length());
int htmlStart = content.indexOf(HTML_START);
int htmlEnd = content.lastIndexOf(HTML_END);
String html;
try {
html = content.substring(htmlStart, htmlEnd + HTML_END.length());
} catch (IndexOutOfBoundsException e) {
// Don't try and prune the string
html = content;
}
// Do the major processing of the actual HTML contents. This is where the magic happens.
processHtmlMessageContent(html);
} catch (MessagingException e) {
logger.error("Error in processing message:", e);
} catch (IOException e) {
logger.error("Error in processing message:", e);
}
} else {
logger.error("DON'T KNOW HOW TO PROCESS [" + message.getPayload().getClass() + "] MESSAGE");
}
logger.info("Done.");
}
問題はconvertStreamToString
またはMimeUtility.decode
にあると思われますが、特定できませんでした。これが に格納されている場合の奇妙な点も除外していませんがCLOB
、可能性は低いと思います。
参考までに、私のconvertStreamToString()
方法は...
protected String convertStreamToString(java.io.InputStream is) {
try {
return new java.util.Scanner(is).useDelimiter("\\A").next();
} catch (java.util.NoSuchElementException e) {
return "";
}
}
変えてみた…
String content = convertStreamToString(MimeUtility.decode(mimeMessage.getDataHandler().getDataSource().getInputStream(), "quoted-printable"));
に...
String content = convertStreamToString(mimeMessage.getDataHandler().getDataSource().getInputStream());
しかし今、私は基本的な MIME デコードを失いました。
また、エンコーディングを取得するために MimeUtility を使用してみました
String encoding = MimeUtility.getEncoding(mimeMessage.getDataHandler().getDataSource());
これが返され、それを使用してみましたが、等号の7bit
ようなものになってしまいます。=3D
デコードされたコンテンツでは、次のようになります。quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
javadocs、ソース、およびオンラインの例を調べましたが、これは実際にはクリックしません。