More Related Content Layout analyzerでのgroovyの利用について
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
プロダクトに 1 から Vue.js を導入した話
Selenium webdriver使ってみようず
20160215 04 java ee7徹底入門 jbatch
What's hot (19) node+socket.io+enchant.jsでチャットゲーを作る
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
Java SE 9の紹介: モジュール・システムを中心に
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
Try_to_writecode_practicaltest #atest_hack
プロダクト開発してわかったDjangoの深〜いパーミッション管理の話 @ PyconJP2017
Glassfish勉強会(JavaEE6について)
Nuxt なしで Vue App 作る時に乗り越えるべき5つの壁
JSR 352 “Batch Applications for the Java Platform”
DjangoでさくっとWeb アプリケーション開発をする話
Similar to Google App Engine for Java (17)
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
JavaEE6 First Application #glassfishjp
Java EE 6で復活するエンタープライズJavaの世界
Java女子部Java EEハンズオン(応用編)ソースコード
Datastoreへのアクセスを楽してMemcacheアクセスに置き換えるライブラリ作った
Easy Going Groovy(Groovyを気軽に使いこなそう)
関ジャバ JavaOne Tokyo 2012報告会
More from Takuya Tsuchida (9)
コンポーネントアプローチによるソフトウェア開発の俊敏性と品質向上の実現~カスタマーショーケース
帳票も今や HTML でつくる時代!?日本の税理士を支えるサーバーレス帳票基盤
Essential Scala 第5章 シーケンス処理
Essential Scala 第4章 トレイトによるデータモデリング
Essential Scala 第3章 オブジェクトとクラス
Essential Scala 第2章 式、型、値
youtube-dl に Pull Request 送ったった
Waze Map Editor クイックスタートガイド
Google App Engine for Java2. Outline
• Google App Engine for Java (GAE/J) といろ
いろ組み合わせるとすごそうなので、
そのすごそうさ具合を説明します。
• 最後に、簡単なデモとその作り方を紹
介します。
6. Google App Engine
• 無料*の PaaS 環境(Python, Java, Go)
• NoSQL データストア (BigTable)
• いろいろなサービスへの API
• そこそこ充実している管理画面
* いろいろな制限はありますが、課金で制限を緩和できます。
9. Why GAE for Java?
• Java は不滅!(あと10年くらいは……)
• Google Web Toolkit (GWT) との親和性
• VMware と Google のクラウド連携強化*
- Spring, Google App Engine, SpringSource Tool Suite
- Spring Roo, Google Web Toolkit
- Spring Insight, Google Speed Tracer
* http://www.vmware.com/jp/company/news/releases/vmware-google.html
10. GAE/J
Specification
• Servlet 2.5
• JSP 2.2 (except Unified EL)
• JSTL 1.1
• JDO 2.3
• JPA 1.0
12. Google Web Toolkit
• Java で AJAX フロントエンドを記述
• JavaScript にコンパイルして実行
• クロスブラウザ(Internet Explorer 6 対応)
• 豊富なウィジェット (3rd party: Ext GWT*)
* http://www.sencha.com/products/extgwt
15. Pre-required
Software
• Java SE Development Kit 6
• Google Chrome (optional)
• 英語のドキュメントに負けない気持ち
20. Pleiades All in One
• 日本語化版 Eclipse +便利プラグイン
• Pleiades = Eclipse プラグイン日本語化プラグイン
• Pleiades All in One for Java Developers 推奨
22. Google Plugin
for Eclipse
• GAE/J & GWT 開発用プラグイン
• ローカル実行用サーバー環境
• GAE デプロイツール
• GWT コンパイラ
23. Ex. Development
Environment
• Windows XP Professional SP3
• Java SE Development Kit 6 Update 31
• Google Chrome 17.0
• Pleiades All in One for Java Developers
(based on Eclipse Indigo 3.7.2)
• Google Plugin for Eclipse*
* Eclipse マーケットプレースからインストールする。
24. Installation Note
• Pleiades のインストールフォルダ*
推奨:C:¥pleiades
自分:C:¥Document and Settings¥takuya¥My Documents¥pleiades
• Google Plugin のインストール
1. Eclipse を起動
2. ヘルプ>Eclipse マーケットプレースをクリック
3. Google Plugin で検索してインストール
* Windows では、パスが長いとインストール(ZIP の解凍)に失敗するそうです。
27. Create GAE Project
1. Eclipse を起動
2. ファイル>新規>プロジェクトをクリック
3. Google>Web アプリケーション・プロジェクトをクリック
4. Windows ファイアウォールの警告:ブロック解除
5. 新規 Web アプリケーション・プロジェクトウィザード
プロジェクト名:Guestbook
パッケージ名:com.example.guestbook
Google Web ツールキットを使用:使用しない
30. Run Application
1. 実行>実行をクリック
2. http://localhost:8888/guestbook にアクセス
• エラーの場合、下記を設定*
1. プロジェクト>プロパティをクリック
2. 実行/デバッグ設定>Guestbook>編集をクリック
3. 引数>VM 引数>につぎの引数を追加
-Dappengine.user.timezone=UTC
* バグみたいです。(2012年3月17日現在)
34. Demo Application
“Guestbook”*
* Google App Engine のサイトにあるチュートリアルをベースにしてつくってます。
40. 1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>Guestbook</title>
6 </head>
7 <body>
8 <h1>Guestbook</h1>
9 <p><a href="#">サインイン</a>するとコメントに名前が表示されます。</p>
10 <p>こんにちは、takuya0301 さん。(<a href="#">サインアウト</a>)</p>
11 <ul>
12 <li>つっちぃ (@takuya0301) です。自己紹介して Twitter ID を晒しましょうw
13 -- takuya0301 (2012-03-24 04:24:43)</li>
14 </ul>
15 <form method="POST" action="/guestbook">
16 <input type="text" size="80">
17 <input type="submit">
18 </form>
19 <p>エラー:コメントを入力してから送信ボタンをクリックしてください。</p>
20 </body>
21 </html>
index.html
45. 16 public class GuestbookServlet extends HttpServlet {
17 public void doGet(HttpServletRequest request, HttpServletResponse response)
18 throws IOException, ServletException {
19 // User サービスの取得
20 UserService userService = UserServiceFactory.getUserService();
21
22 // ログイン中ユーザーの取得(ユーザーがいないときは null)
23 User user = userService.getCurrentUser();
24
25 // ログイン/ログアウト用 URL の生成(引数は戻り URL)
26 String loginURL = userService.createLoginURL(request.getRequestURI());
27 String logoutURL = userService.createLogoutURL(request.getRequestURI());
28
29 request.setAttribute("user", user);
30 request.setAttribute("loginURL", loginURL);
31 request.setAttribute("logoutURL", logoutURL);
32
33 request.getRequestDispatcher("/guestbook.jsp").forward(request, response);
34 }
35 }
GuestbookServlet.java
46. 1 <%@ page contentType="text/html;charset=UTF-8" %>
2 <%@ page trimDirectiveWhitespaces="true" %>
3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
4 <!DOCTYPE html>
5 <html>
6 <head>
7 <meta charset="UTF-8">
8 <title>Guestbook</title>
9 </head>
10 <body>
11 <h1>Guestbook</h1>
12 <%-- ログインユーザーの有無で分岐 --%>
13 <c:choose>
14 <c:when test="${empty user}">
15 <p>
16 <a href="${loginURL}">サインイン</a>するとコメントに名前が表示されます。
17 </p>
18 </c:when>
19 <c:otherwise>
20 <p>
21 こんにちは、${user.nickname} さん。(<a href="${logoutURL}">サインアウト</a>)
22 </p>
23 </c:otherwise>
24 </c:choose>
25 </body>
26 </html>
guestbook.jsp
47. 4. Comment Posting
• HTML フォームからコメントを投稿
• JDO* でコメントを永続化
• エラー処理:空コメント
* JDO (Java Data Objects) は、Java オブジェクトの永続性に関する仕様です。
52. 4 <!DOCTYPE html>
5 <html>
6 <head>
7 <meta charset="UTF-8">
8 <title>Guestbook</title>
9 </head>
10 <body>
11 <h1>Guestbook</h1>
12 <%-- ログインユーザーの有無で分岐 --%>
13 <c:choose>
14 <c:when test="${empty user}">
15 <p>
16 <a href="${loginURL}">サインイン</a>するとコメントに名前が表示されます。
17 </p>
18 </c:when>
19 <c:otherwise>
20 <p>
21 こんにちは、${user.nickname} さん。(<a href="${logoutURL}">サインアウト</a>)
22 </p>
23 </c:otherwise>
24 </c:choose>
25 <%-- コメント投稿フォーム --%>
26 <form method="POST" action="/guestbook">
27 <input type="text" name="comment" size="80"> <input type="submit">
28 </form>
29 <%-- 空コメントの場合、エラーメッセージを表示 --%>
30 <c:if test="${isEmptyCommentError}">
31 <p>エラー:コメントを入力してから送信ボタンをクリックしてください。</p>
32 </c:if>
33 </body>
34 </html>
guestbook.jsp
53. 39 public void doPost(HttpServletRequest request, HttpServletResponse response)
40 throws IOException, ServletException {
41 String comment = request.getParameter("comment");
42
43 // エラー:空コメント
44 if (comment.isEmpty()) {
45 request.setAttribute("isEmptyCommentError", true);
46 doGet(request, response);
47 return;
48 }
49
50 UserService userService = UserServiceFactory.getUserService();
51 User user = userService.getCurrentUser();
52
53 String id = user != null ? user.getUserId() : "";
54 String name = user != null ? user.getNickname() : "";
55 Date postingDate = new Date();
56
57 // コメントオブジェクトの生成
58 Comment c = new Comment(id, name, comment, postingDate);
59
60 // コメントオブジェクトの永続化
61 PersistenceManager pm = PMF.get().getPersistenceManager();
62 try {
63 pm.makePersistent(c);
64 } finally {
65 pm.close();
66 }
67
68 doGet(request, response);
69 }
GuestbookServlet.java
54. 12 @PersistenceCapable
13 public class Comment {
14 @PrimaryKey
15 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
16 private Key key;
17
18 @Persistent
19 private String id;
20
21 @Persistent
22 private String name;
23
24 @Persistent
25 private String comment;
26
27 @Persistent
28 private Date postingDate;
29
30 public Comment(String id, String name, String comment, Date postingDate) {
31 this.id = id;
32 this.name = name;
33 this.comment = comment;
34 this.postingDate = postingDate;
35 }
36
// ゲッターメソッドが続く
56 }
Comment.java
55. 1 package com.example.guestbook;
2
3 import javax.jdo.JDOHelper;
4 import javax.jdo.PersistenceManagerFactory;
5
6 public final class PMF {
7 private static final PersistenceManagerFactory pmfInstance =
8 JDOHelper.getPersistenceManagerFactory("transactions-optional");
9
10 private PMF() {}
11
12 public static PersistenceManagerFactory get() {
13 return pmfInstance;
14 }
15 }
インスタンス生成処理負荷軽減のためのシングルトンラッパークラスです。
PMF.java
58. 10 <body>
11 <h1>Guestbook</h1>
12 <%-- ログインユーザーの有無で分岐 --%>
13 <c:choose>
14 <c:when test="${empty user}">
15 <p><a href="${loginURL}">サインイン</a>するとコメントに名前が表示されます。</p>
16 </c:when>
17 <c:otherwise>
18 <p>
19 こんにちは、${user.nickname} さん。(<a href="${logoutURL}">サインアウト</a>)
20 </p>
21 </c:otherwise>
22 </c:choose>
23 <%-- コメント投稿フォーム --%>
24 <form method="POST" action="/guestbook">
25 <input type="text" name="comment" size="80"> <input type="submit">
26 </form>
27 <%-- 空コメントの場合、エラーメッセージを表示 --%>
28 <c:if test="${isEmptyCommentError}">
29 <p>エラー:コメントを入力してから送信ボタンをクリックしてください。</p>
30 </c:if>
31 <%-- コメントリスト --%>
32 <ul>
33 <c:if test="${not empty newComment}">
34 <li>${newComment.comment} -- ${newComment.name} (${newComment.postingDate})</li>
35 </c:if>
36 <c:forEach var="comment" items="${comments}">
37 <li>${comment.comment} -- ${comment.name} (${comment.postingDate})</li>
38 </c:forEach>
39 </ul>
40 </body>
guestbook.jsp
59. 20 public void doGet(HttpServletRequest request, HttpServletResponse response)
21 throws IOException, ServletException {
/* user, loginURL, logoutURL などを request 属性に設定 */
35 PersistenceManager pm = PMF.get().getPersistenceManager();
36 try {
37 // コメントの取得
38 Query query = pm.newQuery(Comment.class);
39 query.setOrdering("postingDate desc");
40 query.setFilter("postingDate < dateParam");
41 query.declareParameters("java.util.Date dateParam");
42
43 try {
44 // コメント投稿直後の特別処理
45 // コメントがデータストアに反映されていないこともあるので、
46 // 新しいコメントは独立して表示し、それ以前の投稿を取得する。
47 List<Comment> comments;
48 Comment newComment = (Comment) request.getAttribute("newComment");
49 if (newComment != null) {
50 comments = ((List<Comment>) query.execute(newComment.getPostingDate()));
51 } else {
52 comments = (List<Comment>) query.execute(new Date());
53 }
54
55 request.setAttribute("comments", comments);
56
57 request.getRequestDispatcher("/guestbook.jsp").forward(request, response);
58 } finally {
59 query.closeAll();
60 }
61 } finally {
62 pm.close();
63 }
64 } GuestbookServlet.java
60. 66 public void doPost(HttpServletRequest request, HttpServletResponse response)
67 throws IOException, ServletException {
68 // エラー:空コメント
69 String comment = request.getParameter("comment");
70 if (comment.isEmpty()) {
71 request.setAttribute("isEmptyCommentError", true);
72 doGet(request, response);
73 return;
74 }
75
76 // User データの取得
77 UserService userService = UserServiceFactory.getUserService();
78 User user = userService.getCurrentUser();
79
80 String id = user != null ? user.getUserId() : "";
81 String name = user != null ? user.getNickname() : "";
82 Date postingDate = new Date();
83
84 // コメントオブジェクトの生成
85 Comment newComment = new Comment(id, name, comment, postingDate);
86
87 // コメントオブジェクトの永続化
88 PersistenceManager pm = PMF.get().getPersistenceManager();
89 try {
90 pm.makePersistent(newComment);
91 } finally {
92 pm.close();
93 }
94
95 // 新しいコメントを属性として設定
96 request.setAttribute("newComment", newComment);
97
98 doGet(request, response);
99 }
GuestbookServlet.java
65. というか、PaaS 勉強会を
開催しませんか?
AWS Elastic Beanstalk も熱いですね。Windows Azure や Heroku も興味あります。
てか、PaaS 勉強会って絶対あると思うんで調べて参加しろって話ですね。