SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Google App Engine for JavaでMySQLを使ってみる

Google App Engine for JavaでMySQLを使ってみる


ステップ3:プログラムの記述

 GAEプロジェクトの生成によって、「Hello world!」を表示する簡単なサンプルプログラム(サーブレットとHTML)が自動生成されます。生成されているプログラムのコードを上書きするのが効率的です。

[A]サーブレットコードの記述

 最初にサーブレットですが、ここでは自動生成されるサーブレット名GuestbookServletをそのまま使用してコードをリスト1で上書きします。ただしpackage指定は、プロジェクト生成時に指定したpackage名に修正してください。

リスト1 GuestbookServlet.java
package guestbook;
import com.google.appengine.api.rdbms.AppEngineDriver;    //(1)
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class GuestbookServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
    throws IOException {
resp.setContentType("text/html; charset=utf-8");    //(2)
        PrintWriter out = resp.getWriter();
        Connection con = null;
        try {
            DriverManager.registerDriver(new AppEngineDriver());    //(3)
            con = DriverManager.getConnection("jdbc:google:rdbms://branecosmology:cloudsqlsample/guestbook");    //(4)
            String fname = req.getParameter("fname");
            String content = req.getParameter("content");
            if (fname == "" || content == "") {
                out.println("<html><body>メッセージまたは名前が入力されていません。 3秒後に画面が再表示されます..</body></html>");
            } else {
                String statement ="INSERT INTO entries (guestName, content) VALUES( ? , ? )";    //(5)
                PreparedStatement stmt = con.prepareStatement(statement);
                stmt.setString(1, fname);
                stmt.setString(2, content);
                int success = 2;
                success = stmt.executeUpdate();    //(6)
                if(success == 1) {
                    out.println("<html><body>成功!! 3秒後 に画面が再表示されます..</body></html>");
                } else if (success == 0) {
                    out.println("<html><body>失敗! やり直してください! 3秒後に画面が再表示されます..</body></html>");
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (con != null) 
                try {
                    con.close();
                } catch (SQLException ignore) {
            }
        } 
        resp.setHeader("Refresh","3; url=/guestbook.jsp");    //(7)
    }
}

 このサーブレットはRDBアクセスを行うごく普通のコードに見えますが、ポイントになる点を述べてみます。

  • (1)JDBCドライバの指定
    import com.google.appengine.api.rdbms.AppEngineDriver;
    

     Cloud SQLを使用するJavaアプリケーションでは専用のドライバ(JDBCドライバ)を使用する必要がありますが、Eclipse用のGoogle Pluginにはこの専用ドライバが用意されており、上記のimport文で指定します。

  • (2)日本語表示に対応
    resp.setContentType("text/html; charset=utf-8");
    

     GoogleのCloud SQLサイトにはサンプルが掲載されていますが、この記述がないためそのまま使用した場合日本語の文字バケが発生します。当然の指定とも言えますが、確認のためここで取り上げています。

  • (3)専用ドライバをDriverManagerに登録
    DriverManager.registerDriver(new AppEngineDriver());
    

     専用ドライバのインスタンスを生成し、これをJDBCドライバとしてDriverManagerに登録しています。

  • (4)指定されたデータベースへの接続
    con = DriverManager.getConnection("jdbc:google:rdbms://branecosmology:cloudsqlsample/guestbook");
    

     指定されたデータベースのURLへ接続を行っています。データベース接続ではユーザー名とパスワードを指定できます。設定するにはまず、SQL Prompt画面からGRANT文でユーザーとパスワードを作成します。例えば、パスワード「pass1」のユーザー「user1」に、すべてのデータベース/テーブルに対して登録と参照を許可する場合には次のSQL文を実行します。

    GRANT INSERT,SELECT ON *.* TO user1 IDENTIFIED BY 'pass1';
    

     次に、リスト1でデータベース接続を行う(4)を次のように変更します。

    con = DriverManager.getConnection("jdbc:google:rdbms://branecosmology:cloudsqlsample/guestbook", "user1", "pass1");
    
  • (5)~(6)SQL文の指定と実行

     (5)で登録用のSQL文を指定していますが、通常のMySQLのSQL文です。ここでは動的SQLを使用しているため、SQL文の値指定では「?」を使用し、実際の値はその下のsetStringメソッドで文字列として指定されています。ここまででSQL文実行の準備は完了し、その後(6)の.executeUpdate()で登録を実行しています。

  • (7)JSPのリダイレクト指定

     メッセージの登録では、3秒で画面が再表示されますが、これは(6)のsetHeaderメソッドで行われています。

     setHeaderはクライアントにレスポンスを返す際にヘッダーを新規に追加したり上書きしたりできます。ここでは3秒後に、JSPのページに自動的にジャンプすることを指定していますが、これはHTMLヘッダで<meta http-equiv="refresh" content="3;URL=/guestbook.jsp">と指定しているのと等価です。

[B]JSPの記述

 次に、JSPのコード記述を行います。JSPでは、画面ロード時に登録済のメッセージを全件表示し、その下のHTMLで記述されたフォームから新しいメッセージを登録するようになっています。Cloud SQL用のJDBCドライバ設定などは、サーブレットのサンプルで確認しているので問題ありません。そのほかは、普通のJSPプログラムです。

リスト2 guestbook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="java.sql.*" %>
<%@ page import="com.google.appengine.api.rdbms.AppEngineDriver" %>
<html>
<body>
<%
Connection con = null;
con = DriverManager.getConnection("jdbc:google:rdbms://branecosmology:cloudsqlsample/guestbook");
ResultSet rs = con.createStatement().executeQuery("SELECT guestName, content, entryID FROM entries");     //(1)
%>
<table border="1" bordercolor="#bbbbbb" cellspacing="0" cellpadding="0" width="440">
<tr>
<th width="22%" style="background-color: #CCFFCC; margin: 5px">名前</th>
<th style="background-color: #CCFFCC; margin: 5px">メッセージ</th>
<th width="7%" style="background-color: #CCFFCC; margin: 5px">ID</th>
</tr> 
<%
while (rs.next()){     //(2)
    String guestName = rs.getString("guestName");
    String content = rs.getString("content");
    int id = rs.getInt("entryID"); 
%>
<tr>
<td><%= guestName %></td>
<td><%= content %></td>
<td><%= id %></td>
</tr>
<% }
con.close(); %>
</table>
<hr />
<p><strong>ゲストブックにメッセージ書き込み</strong></p>
<form action="/sign" method="post">
    <div>名前: <input type="text" name="fname" /></div>
    <div>メッセージ:
    <br /><textarea name="content" rows="3" cols="60"></textarea>
    </div>
    <div><input type="submit" value="メッセージ送信" /></div>
    <input type="hidden" name="guestbookName" />
</form>
</body>
</html>

[C]web.xmlの記述

 自動生成されているweb.xmlを、次のように修正します。

リスト3 web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
    <servlet>
         <servlet-name>sign</servlet-name>
         <servlet-class>guestbook.GuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
         <servlet-name>sign</servlet-name>
         <url-pattern>/sign</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
         <welcome-file>guestbook.jsp</welcome-file>
    </welcome-file-list>
</web-app>

次のページ
サンプルをクラウド環境にデプロイ

この記事は参考になりましたか?

Google App Engine for JavaでMySQLを使ってみる連載記事一覧
この記事の著者

清野 克行(セイノ カツユキ)

慶應義塾大学工学部電子物理専攻卒。日本IBM、日本HPで、製造装置業を中心とした業務系/基幹業務系システムのSE/マーケティングや、分散アプリケーションによる社内業務システム開発などに携わる。現在は、クラウドやAjax関連の/ソフト開発/書籍執筆/セミナー講師/コンサルティング、などを行っている。情...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/6444 2012/04/12 19:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー