気まぐれラボラトリィ

自分の日常とへんてこなコードと大好きなニコニコ動画と
適当すぎるWebページと・・・
labo.neco-labo.com

2009年 09月21日(月)

java初心者がAppEngineで初めてのBigTable。落書き帳完成。

Googleインフラ上でWebアプリケーションを動作させることが可能な、GoogleAppEngineというものがと〜っても気になりだしている今日この頃。

このAppEngineの言語にjavaが追加されてから少し経つのですが、

いまさらながらそのjavaを使って何か作ってみよう(というか、作り方の勉強)というわけです。

唐突な流れで。eclipseインストールして。AppsEngineのプラグイン入れて。


javaでwebアプリを作るとなるともちろんservletサーブレット)を使うことになります。で、私はサーブレットを作るのもままならない程度の能力しか持ち合わせていないのですが

まぁ、何とかなるでしょう。特殊なdatastore(データストア)とやらを除いて。


datastoreとは簡単に言うとAppEngine専用データベースである。AppEngineでは、サーバー上に普通にファイル保存は出来ないのでデータを保存する場合はすべてdatastoreに保存する必要がある。

で、このdatastoreなのだが巷でよく使われるリレーショナルデータベースRDB)とは違う。キーバリューストアというタイプなのだとか。なぜ、Googleはこのタイプを使うのかというとRDBではGoogle先生にとって遅すぎるらしい。ちなみにGoogleが作ったこのデータストアの名称は「BigTable」。まぁ、こんな話はどうでもいい。先に進めよう。


で、このdatastoreを使うのが厄介だった。

やってみると、RDBみたいにデータベースに対しテーブル定義を行いそしてデータをがんがん入れていくのではなく

javaオブジェクトでデータを定義してそのオブジェクトデータベースに入れるような感じでコーディングを行うというイメージだった。(私の個人的なイメージ)


Googleの説明通り作るだけなのだがlong型はlongではなくラッパークラスのLongを使わなければいけないところを少し悩んでしまったり、

文字化けしてぜんぜん使えねぇーーー」と悩んでいたらただ単にサーブレットの文字エンコーディングをちゃんと設定してなかっただけだったりと、へたれプログラマーぶりを遺憾なく発揮した作業であった。もちろん、自分の足につまづくことも忘れなかった。


そんなことして何を作ったかというと、名前とコメントを入れて送信ボタンを押すと

掲示板みたいに一言メッセージとして登録されるという至極どーでもいいWebアプリである。


以下、私が無駄に時間をかけて作ってみたソースである。

(無駄に時間がかかったのはEclipseが重いせいですよ?そのうちPC自作します。)

あまり参考にはならないけど。


package cc.co.necoLabo.dataTest;

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 Message {

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Long id;

	@Persistent
	private String name;

	@Persistent
	private String message;

	/**
	 * idを取得します。
	 * @return id
	 */
	public Long getId() {
	    return id;
	}

	/**
	 * nameを取得します。
	 * @return name
	 */
	public String getName() {
	    return name;
	}

	/**
	 * nameを設定します。
	 * @param name name
	 */
	public void setName(String name) {
	    this.name = name;
	}

	/**
	 * messageを取得します。
	 * @return message
	 */
	public String getMessage() {
	    return message;
	}

	/**
	 * messageを設定します。
	 * @param message message
	 */
	public void setMessage(String message) {
	    this.message = message;
	}
}
  • MessageServlet.java
package cc.co.necoLabo.dataTest;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MessageServlet extends HttpServlet {

	private static final long serialVersionUID = -2743084515697088124L;

	@SuppressWarnings("unchecked")
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException,IOException {

		response.setContentType("text/html; charset=utf-8");
		PrintWriter pw = response.getWriter();
		pw.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" +
				"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"ja\" lang=\"ja\">\n" +
				"<head>");
		pw.println("<title>落書き ぼ〜ど。</title>");
		pw.println("</head>\n<body>");
		pw.println("<p>落書き ぼ〜ど。</p>");
		pw.println("<form method=\"post\" action=\"./\">");
		pw.println("  名前: <input type=\"text\" name=\"name\"><br />");
		pw.println("コメント: <input type=\"text\" name=\"comm\"><br />");
		pw.println(" <input type=\"submit\" value=\"送信\">");
		pw.println("</form><br />");

		PersistenceManager pm = PMF.get().getPersistenceManager();
		try{
			String query = "select from " + Message.class.getName() +" order by id desc";
			Query query1 = pm.newQuery(query);

			List<Message> results = (List<Message>) query1.execute();

			if (results.iterator().hasNext()) {
	            for (Message m : results) {
	            	pw.println("<p>");
	            	pw.println("id:" + m.getId() + "<br />");
	            	pw.println("Name:" + m.getName() + "<br />");
	            	pw.println("Message:" + m.getMessage() + "<br />");
	            	pw.println("<br /></p>");
	            }
	        } else {
	            // ... no results ...
	        }
		}finally{
			pm.close();
		}

		pw.println("</body></html>");
	}

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		req.setCharacterEncoding("utf-8");

		Message mess = new Message();

		PersistenceManager pm = PMF.get().getPersistenceManager();
		try{
			mess.setName(req.getParameter("name"));
			mess.setMessage(req.getParameter("comm"));

			pm.makePersistent(mess);
		}finally{
			pm.close();
		}
		resp.sendRedirect("../message/");
	}

}

Googleのドキュメントに書いてあるものと同様なので省略。

Error 404 (Not Found)!!1




動かしてみたページがこれ

Error 404 (Page not found)!!1

って、激しく文字化けしてないですか?サーブレットでは文字エンコードutf-8に設定してるんだけど・・・。




とまぁ、こんな感じです。

そのままだとXSSとかの脆弱性満載の超危険サイトと化すので対策しましょうww


これだけのものを作るのに数時間かけてしまった・・・。

しかも、EclipsePleiadesオールインワンの全部入りUltimateなやつをなぜかダウンロードしたので糞重い!

早くPC組みたいのだが、Win7まで待つし、グラボも新しいやつが出るまで待つ。

いつになるのやら。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証