2010/02/19

mobyletでSMTP認証を利用する

前回の記事でmobyletではSMTP認証を利用したメール送信ができないと書きましたが、いくつかのクラスを拡張することによってSMTP認証の利用は可能となります。その方法についてまとめてみました。

1. MobyletMailConfig
mobylet標準のメール設定保持クラス(MobyletMailConfig)では、SMTP認証を行う場合のプロパティ(mail.smtp.auth)の設定を行えないため、MobyletMailConfigの拡張クラスを作成します。
  1. /** 
  2.  * メール送信時にSMTP認証を行うように設定するための設定情報クラスです。 
  3.  *  
  4.  * @author namiki 
  5.  *  
  6.  */  
  7. public class MyMobyletMailConfig extends MobyletMailConfig {  
  8.   
  9.     /** SMTP認証設定のキーです。 */  
  10.     private static final String KEY_SMTP_AUTH = "mobylet.smtp.auth";  
  11.   
  12.     /** SMTP認証の初期値です。 */  
  13.     private static final String DEF_SMTP_AUTH = "false";  
  14.   
  15.     /** 
  16.      * コンストラクタです。 
  17.      */  
  18.     public MyMobyletMailConfig() {  
  19.         super();  
  20.     }  
  21.   
  22.     /** 
  23.      * SMTP認証設定を取得します。 
  24.      *  
  25.      * @return SMTP認証設定 
  26.      */  
  27.     public String getSMTPAuth() {  
  28.         String smtpAuth = props.getProperty(KEY_SMTP_AUTH);  
  29.         if (StringUtils.isEmpty(smtpAuth)) {  
  30.             smtpAuth = DEF_SMTP_AUTH;  
  31.         }  
  32.         return smtpAuth;  
  33.     }  
  34.   
  35.     @Override  
  36.     public Session createSession() {  
  37.         Properties sessionProperties = new Properties();  
  38.         sessionProperties.setProperty("mail.host", getHost());  
  39.         sessionProperties.setProperty("mail.smtp.host", getHost());  
  40.         sessionProperties.setProperty("mail.smtp.localhost", getHost());  
  41.         sessionProperties.setProperty("mail.smtp.port", getPort());  
  42.         sessionProperties.setProperty("mail.smtp.user", getUser());  
  43.         sessionProperties.setProperty("mail.smtp.pass", getPassword());  
  44.         sessionProperties.setProperty("mail.smtp.auth", getSMTPAuth());  
  45.         return Session.getInstance(sessionProperties);  
  46.     }  
  47.   
  48. }  


2. MobyletMailInitializer
mobylet標準のコンポーネント初期化クラスであるMobyletInitializerでは、1.で作成したMailConfigクラスを生成できないので、MobyletMailInitializerの拡張クラスを作成します。
  1. /** 
  2.  * Mobyletでメール送信を行うためのコンポーネント初期化クラスです。 
  3.  
  4.  * Mobylet標準の{@link org.mobylet.mail.initializer.MobyletMailInitializer} 
  5.  * が行う初期化処理に加えて、 SMTP認証の設定を行うクラスを初期化します。 
  6.  *  
  7.  * @author namiki 
  8.  *  
  9.  */  
  10. public class MyMobyletMailInitializer extends MobyletMailInitializer {  
  11.     @Override  
  12.     public void initialize() {  
  13.         super.initialize();  
  14.         SingletonUtils.put(new MyMobyletMailConfig());  
  15.     }  
  16. }  


3. mobylet.mail.properties
mobyletのメール設定ファイルであるmobylet.mail.propertiesに新しいプロパティ設定を追加します。
  1. mobylet.smtp.host=192.168.1.1  
  2. mobylet.smtp.port=587  
  3. mobylet.smtp.user=sample@example.com  
  4. mobylet.smtp.password=aaaaa  
  5. # 新しいプロパティです。  
  6. mobylet.smtp.auth=true  


4. MobyletMessage
次にMobyletMessageを拡張します。MobyletMessageはjavax.mail.Sessionを保持していますが、アクセス修飾子がprotectedとなっているため、後述するMobyletMailerのサブクラスからアクセスできないので、アクセスできる状態にするように拡張します。
  1. /** 
  2.  * {@link org.mobylet.mail.message.MobyletMessage}では{@link javax.mail.Session} 
  3.  * にアクセスできないため、{@link javax.mail.Session}へのアクセスを確保するためのメッセージクラスです。 
  4.  *  
  5.  * @author namiki 
  6.  *  
  7.  */  
  8. public class MyMobyletMessage extends MobyletMessage {  
  9.   
  10.     private Session localSession;  
  11.   
  12.     /** 
  13.      * コンストラクタです。 
  14.      *  
  15.      * @param toCarrier 
  16.      *            キャリア情報 
  17.      * @param session 
  18.      *            セッション情報 
  19.      */  
  20.     public MyMobyletMessage(Carrier toCarrier, Session session) {  
  21.         super(toCarrier, session);  
  22.         this.localSession = session;  
  23.     }  
  24.   
  25.     /** 
  26.      * セッション情報を返却します。 
  27.      *  
  28.      * @return 
  29.      */  
  30.     public Session getSession() {  
  31.         return this.localSession;  
  32.     }  
  33.   
  34. }  


5. MobyletMailer
実際にメールを送信するMobyletMailerの拡張クラスを作成します。MobyletMessageのサブクラスを返却するcreateMessage()と実際にメール送信を行うsend()を実装します。
  1. /** 
  2.  * mobyletのメール送信でSMTP認証を行うメール送信クラスです。 
  3.  *  
  4.  * @author namiki 
  5.  *  
  6.  */  
  7. public class MyMobyletMailer extends MobyletMailer {  
  8.   
  9.     /** 
  10.      * 指定された送信先アドレスをもとに、メッセージを作成します。 
  11.      *  
  12.      * @param to 
  13.      *            送信先アドレス 
  14.      * @return メッセージ 
  15.      */  
  16.     public static MyMobyletMessage createMessage(String to) {  
  17.   
  18.         MailConfig config = SingletonUtils.get(MailConfig.class);  
  19.         Session session = config.createSession();  
  20.         // Carrier  
  21.         MailCarrierDetector carrierDetector = SingletonUtils  
  22.                 .get(MailCarrierDetector.class);  
  23.         Carrier carrier = carrierDetector.getCarrierByAddress(to);  
  24.         // Message  
  25.         MyMobyletMessage message = new MyMobyletMessage(carrier, session);  
  26.         return (MyMobyletMessage) message.to(to);  
  27.   
  28.     }  
  29.   
  30.     /** 
  31.      * 指定されたメッセージをSMTP認証でメールを送信します。 
  32.      *  
  33.      * @param message 
  34.      *            メッセージ 
  35.      */  
  36.     public static void sendBySMTP(MyMobyletMessage message) {  
  37.   
  38.         Session session = message.getSession();  
  39.         Transport transport = null;  
  40.         try {  
  41.             transport = session.getTransport("smtp");  
  42.             transport.connect(session.getProperty("mail.smtp.host"), session  
  43.                     .getProperty("mail.smtp.user"), session  
  44.                     .getProperty("mail.smtp.pass"));  
  45.             transport.sendMessage(message.construct(), message  
  46.                     .getAllRecipients());  
  47.             transport.close();  
  48.   
  49.         } catch (Exception e) {  
  50.             e.printStackTrace();  
  51.         }  
  52.     }  
  53. }  


6. 使い方
最後にこれらのクラスを使ったメール送信の方法です。
  1. /** 
  2.  * Mobyletの機能を利用して、メール送信を行うロジッククラスです。 
  3.  *  
  4.  * @author namiki 
  5.  *  
  6.  */  
  7. public class MobyletMailSenderLogic {  
  8.   
  9.     // ------------------------------------------------------------ [Properties]  
  10.   
  11.     /** メールメッセージオブジェクトです。 */  
  12.     private MailMessageDto messageDto;  
  13.   
  14.     // -------------------------------------------------------------- [Accessor]  
  15.   
  16.     /** 
  17.      * @param messageDto 
  18.      *            the messageDto to set 
  19.      */  
  20.     public void setMailMessageDto(MailMessageDto messageDto) {  
  21.         this.messageDto = messageDto;  
  22.     }  
  23.   
  24.     // -------------------------------------------------------- [Public methods]  
  25.   
  26.     public void send() {  
  27.   
  28.         if (messageDto.to.length <= 0) {  
  29.             throw new RuntimeException("送信先アドレスが定義されていません。");  
  30.         }  
  31.   
  32.         for (int i = 0; i < messageDto.to.length; i++) {  
  33.             MyMobyletMessage message = MyMobyletMailer  
  34.                     .createMessage(messageDto.to[i]);  
  35.   
  36.             MessageBody body = new MessageBody();  
  37.             body.setText(MyEmojiUtils  
  38.                     .convertEmojiCharByKey(messageDto.bodyText));  
  39.   
  40.             message.from(messageDto.from).subject(  
  41.                     MyEmojiUtils.convertEmojiCharByKey(messageDto.subject))  
  42.                     .setBody(body);  
  43.   
  44.             MyMobyletMailer.sendBySMTP(message);  
  45.   
  46.         }  
  47.     }  
  48. }  

上記のMailMessageDtoは送信元メールアドレス、送信先メールアドレス、件名、本文を保持するためのクラスです。MessageDto.toの数だけ処理を繰り返していますが、これは送信先のキャリアによって絵文字の文字コードを変更する必要があるためです。

以上がmobyletでSMTP認証を利用する場合の方法となります。かなり大急ぎで作ったものなので、エラーハンドリングをほとんど無視していたり、作り自体まだまだ詰めが甘いと思いますが、参考になれば幸いです。

0 件のコメント:

コメントを投稿