GAEでデータストア登録 -サークルIT化のお手伝い

移転しました。

勝手に思ってるサークルの問題点に勝手に取り組むシリーズ改め、「サークルIT化のお手伝い」で引き続きやっていこうと思います。今回は、GAEでデータストア登録です。

おさらい -こんなことがしたいんです!

新入生からのメールに対して、自動でGmailにアドレスを登録するところまで持ってきたい。
gae1

今回は、メール受信から次の3つを取得してデータストアに登録します。

  • メールアドレス
  • 件名
  • 本文

件名に自分の名前を入れてもらえれば、メールアドレスと件名を取得して、アドレス帳ができる。本文に記入するのは、予備ってことで。

今回も Google App Engine for Javaでのメール受信コード -きしだのはてな のソースを参考にしています。


今回新たに、

を付け加えました。データストアに登録するのって難しいです>_< いまいちよくわかってません。

そんで、デプロイ。GAE宛にメールを送ってみると・・・・

ちゃんとデータストアに登録されました!!感激♪
スクリーンショット(2010-09-23 10.13.10)


次は、Gmailにインポートするためのcsv出力ですね。



ソース

PMF.java
package javamail.util;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

//永続化マネージャを管理
public final class PMF {
	private static final PersistenceManagerFactory pmfInstance =
		JDOHelper.getPersistenceManagerFactory("transactions-optional");
	private PMF() {}
	public static PersistenceManagerFactory get(){
		return pmfInstance;
	}
}
ReceivedMail.java
package javamail;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class ReceivedMail {
	@PrimaryKey
	@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
	private Long id;
	
	@Persistent
	private String from;
	
	@Persistent
	private String subject;
	
	@Persistent
	private String text;

	
	public String getFrom() {
		return from;
	}

	public String getSubject() {
		return subject;
	}

	public String getText() {
		return text;
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public void setText(String text) {
		this.text = text;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Long getId() {
		return id;
	}
}
JavaMailServlet.java
package javamail;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Properties;

import javamail.util.PMF;

import javax.jdo.PersistenceManager;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class JavaMailServlet extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		

		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);

		try {
			MimeMessage message = new MimeMessage(session, req.getInputStream());

			ReceivedMail mail = new ReceivedMail();
			mail.setSubject(message.getSubject());
			//ローカルサーバーでは文字化けするので次のようなコードが必要。本番サーバーでは不要
			//mail.setSubject(new String(message.getSubject().getBytes("8859_1"), "UTF-8"));
			mail.setFrom(parseFrom(message.getFrom()[0].toString()));
			
			String contentType = message.getContentType();
			InputStream is = null;
			String mess = "";

			if(message.isMimeType("text/plain")){
				//ふつうのメールの処理
				mess = (String)message.getContent();
			}else{
				//HTMLメールや添付メールの処理
				Multipart content = (Multipart)message.getContent();

				for(int i = 0; i < content.getCount(); ++i){
					BodyPart bp = content.getBodyPart(i);
					if(!bp.isMimeType("text/plain")) continue;
					is = bp.getInputStream();

					contentType = bp.getContentType();
					break;
				}
			}
			if(is != null){
				//contentTypeからエンコーディングを取得
				String encoding = null;
				String[] elms = contentType.split(";");
				for(String elm : elms){
					if(elm.trim().startsWith("charset=")){
						encoding = elm.trim().substring("charset=".length());
					}
				}

				Reader r = null;
				if(encoding != null){
					//エンコーディングが入っている
					if(encoding.startsWith("\"")) encoding = encoding.substring(1);
					if(encoding.endsWith("\"")) encoding = 
						encoding.substring(0, encoding.length() - 1);
					r = new InputStreamReader(is, encoding);
				}else{
					//エンコーディングが入っていない
					r = new InputStreamReader(is);
				}

				BufferedReader buf = new BufferedReader(r);
				for(String line; (line = buf.readLine()) != null;){
					mess += line + "\n";
				}
			}
			
			//パース処理
			ArrayList<String> sets = new ArrayList<String>();
			for (String str : mess.split("\n")) {
				sets.add(str);
			}
			
			String changedmess = "";
			for (String set : sets) {
				changedmess += set;
			}
			
			mail.setText(changedmess);
			pm.makePersistent(mail);

		} catch (MessagingException ex) {
			ex.printStackTrace();
		} finally {
			pm.close();
		}
	}
	
	//アドレス部分だけ抜き出す
	private String parseFrom(String from){
		return from.substring(from.indexOf("<") + 1, from.lastIndexOf(">"));
	}
}