SpringはMIMEもサポートしているらしいので,試してみた.
SpringでのMIMEサポート
メール送信処理の記述
setText
サンプル実行
SpringでのMIMEサポート
Springでの,MIMEサポートは以下のような状況である.
MailSenderの実装クラスはJavaMailSender.
MIME形式のメールを構築するためのヘルパークラスがある.
このように,さほど大がかりなものではないが,文字コードの扱いに関して,APIとしてややこしい部分があるので,その点に注意. 本頁のサンプルでは,MIMEで非マルチパートメールとマルチパートメールを送信するものを作成した.
メール送信処理の記述
メール送信処理を記述する,MimeMailBLImplを以下に示す.
package org.fireproject.springsample;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMailMessage;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.apache.log4j.Logger;
public class MimeMailBLImpl implements MailBL {
/** ログ出力用. */
private static Logger logger = Logger.getRootLogger();
/** メール送信処理クラス. */
private JavaMailSender mailSender;
/** メールメッセージプロトタイプ. */
private SimpleMailMessage origMessage;
/** メール出力文字コード. */
private static String MAIL_CHAR_SET = "ISO-2022-JP";
public void setMailSender(JavaMailSender param) {
mailSender = param;
}
public JavaMailSender getMailSender() {
return mailSender;
}
public void setMessage(SimpleMailMessage param) {
origMessage = param;
}
public SimpleMailMessage getMessage() {
return origMessage;
}
public void process() {
process(false);
}
/**
* ビジネスロジックを実行する.
*/
public void process(boolean multiPartFlag) {
if (multiPartFlag) {
processMultiPart();
} else {
processUniPart();
}
}
/**
* UniPart版.
*/
public void processUniPart() {
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws MessagingException {
// mimeMessage.setSubject(origMessage.getSubject() + " UniPart版サブジェクト", MAIL_CHAR_SET);
// mimeMessage.setText("UniPart版メール本文.", MAIL_CHAR_SET);
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, false, MAIL_CHAR_SET);
message.setFrom(origMessage.getFrom());
message.setTo(origMessage.getTo());
message.setSubject(origMessage.getSubject() + " / UniPart版サブジェクト");
message.setText("UniPart版メール本文.");
}
};
try{
mailSender.send(preparator);
} catch(MailException me) {
logger.error("failed to send mail", me);
}
}
/**
* MultiPart版.
*/
private void processMultiPart() {
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws MessagingException {
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, MAIL_CHAR_SET);
message.setFrom(origMessage.getFrom());
message.setTo(origMessage.getTo());
message.setSubject(origMessage.getSubject() + " / MultiPart版サブジェクト");
message.setText("MultiPart版メール本文");
message.addInline("log4j.xml", new FileSystemResource("conf/log4j.xml.eucjp"));
message.addAttachment("build.xml", new FileSystemResource("conf/build.xml.eucjp"));
}
};
try{
mailSender.send(preparator);
} catch(MailException me) {
logger.error("failed to send mail", me);
}
}
}
BeanFactoryにより,mailSenderにはJavaMailSenderImplが設定されている. 二つのメソッドprocessUniPart,processMultiPartが本頁の本題である. 前者が非マルチパートメール,後者がマルチパートメールを送信する. Springでは,MIMEメッセージを作成するには,MimeMessagePreparatorを使用してJavaMailSenderImpl#send(MimeMessagePreparator)から呼び出すコールバックメソッドを実装する.
MimeMessagePreparator preparator = new MimeMessagePreparator() {
MimeMessagePreparatorはインタフェースで,サンプルのようにコールバックprepare(MimeMessage)メソッドを実装する. このメソッド内で,具体的にどういったメールを生成するかといった処理を記述する. SpringではMIMEメール生成のためのヘルパークラスとして,MimeMessageHelperがある. いくつかのコンストラクタがあり,以下がもっとも設定の多いものである.
MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, String encoding)
引数について以下に記述する.
mimeMessage.
MimeMessageHeloperは内部でこれを編集するのだが,prepareメソッドの引数を渡すことで,JavaMailSenderImplに編集結果を渡す. したがって,決めでprepareメソッドの引数を渡す.
multipart
作成するメールがマルチパートか否かのフラグを設定する. したがってサンプルでは,メソッドprocessUniPartではfalse,processMultiPartではtrueを設定している.
encoding
文字コードを記述する. サンプルでは日本語を記述するので,ISO-2022-JP(定数MAIL_CHAR_SET)を設定している.
あとは,いつものようにsetToやらsetSubjectやらすればよい. MimeMessageHelperはコンストラクタでencodeが指定されていると,setSubjectやsetTextの際にそのエンコードを適用するので,毎回文字コードを指定する必要がない点に注意. したがって,
message.setSubject(origMessage.getSubject() + " / UniPart版サブジェクト");
message.setText("UniPart版メール本文.");
は,サンプルでコメントアウトされている
mimeMessage.setSubject(origMessage.getSubject() + " UniPart版サブジェクト", MAIL_CHAR_SET);
mimeMessage.setText("UniPart版メール本文.", MAIL_CHAR_SET);
と等価となる. processMultiPartにあるように,MimeMessageHelperでは,
addInline
addAttachment
などが提供されており,マルチパートメールの作成を補助してくれる. なお,setTextは,addInlineやaddAttachmentより先に呼び出さなければならない.
setText
MimeMessageHelperを使用すると,いちいちsetTextなどをする際に文字コードを指定する必要がない. コンストラクタのものが設定される. MimeMessageHelper#setTextには,その設定が楽になった分,HTMLメールか否かの引数がある.
setText(String text)
通常のテキストを設定する.
setText(String text, boolean html)
第二引数で,HTMLメールか否かを指定する. 第二引数に応じて,Content-Typeがtext/htmlに変化する.
setText(String plainText, String htmlText)
プレーンテキストと,HTMLテキストの両方を設定する. これは両方メールに記述し,メールクライアントにて表示を選択するようなメールである.
サンプル実行
本頁のサンプルドライバを以下に示す.
package org.fireproject.springsample;
import java.net.URL;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.util.Locale;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.log4j.Logger;
public class HelloSpringMailSender {
/** ログ出力用. */
private static Logger logger = Logger.getRootLogger();
public static void main (String args[]) throws IOException {
boolean multiPartFlag = false;
if (args.length == 1) {
multiPartFlag = "true".equals(args[0]);
}
ApplicationContext context = null;
context = getApplicationContext();
// メール送信ビジネスロジックの取得.
MailBL mailBL = (MailBL)context.getBean("mailBL");
mailBL.process(multiPartFlag);
}
/**
* ApplicationContextを生成して返す.
* 要素importによるbeans.xmlの分割.
*
* @return ApplicationContextオブジェクト
*/
private static ApplicationContext getApplicationContext() {
logger.info("getApplicationContext start");
// ClassLoaderがうまくbeans.xmlを見付けられない場合や,
// jarファイル内にbeans.xmlがある場合は,以下のようにする.
URL url = HelloSpringMailSender.class.getResource("beans.xml");
Resource res = new UrlResource(url);
XmlBeanFactory factory = new XmlBeanFactory(res);
GenericApplicationContext ctx = new GenericApplicationContext(factory);
ctx.refresh();
return ctx;
}
}
サンプルを実行する前に,
conf/mail.conf
に,メールの設定を記述する. サンプルを実行すると実際にメールを送信するので,送信先などに注意する. 実行には,引数でマルチパートメールか否かを指定する.
$> java -jar springsample.jar false
あとは,宛先でメールを受信して内容を確認する.