More Related Content Similar to T2 - 関ジャバ1月27日 Similar to T2 - 関ジャバ1月27日 (20) T2 - 関ジャバ1月27日1. Copyright 2010 The Team T2 Framework and the others All Rights Reserved. つなぐ、つながる、つないでなんぼ! Web フレームワーク 「 T2 」 の紹介 Go Tanaka <tanago3@gmail.com> 2. 自己紹介 田中 豪 ( たなか ごう ) Blog: http://d.hatena.ne.jp/tan_go238/ Twitter: http://twitter.com/tan_go238/ 6. つなぐ、つながる! 自分の使いやすいものをつなげて使おう! DI コンテナ Seasar, Spring, Guice, Lucy, 内部 DI コンテナ OR マッパー S2Dao, DBFlute, Doma, Hibernate, iBatis テンプレートエンジン JSP, ZPT, Mayaa... サンプルもいっぱいあるよ! 11. @GET と @ActionPath を使ったサンプル メソッドアノテーション @Page(“/hello”) public class Hoge { @GET @ActionPath(“/world”) public Navigation helloWorld(){ … } } http://yoursite.com/app/ hello / world 12. メソッドアノテーション @Page(“/hello”) public class Hoge { @POST @ActionParam public Navigation add (WebContext context){ … } } @POST と @ActionParam を使ったサンプル <form name="addForm" action=" /{cx}/hello ” method=" post "> <input type="text" name="arg1" /><br /> <input type="submit" name=" add " value=" 送信 "/> </form> @ActionParam だけだと メソッド名=ボタンの name 属性 と認識 14. @ActionParam メソッドアノテーション @Page(“/hello”) public class Hoge { @ POST @ActionParam(“add.x”) public Navigation imgTest(WebContext context){ … } } T2 のサンプルには下記のように @ActionParam に .x がついたものがあるが これは画像を使った input type=image のときに IE が name 属性 add の名前に対して .x をつけてポストしてくるため <input type=“image” name=“add” ~ 15. @Ajax を使ったサンプル(1) メソッドアノテーション @Page("/ajaxJQuery") public class AjaxJQueryPage { @Ajax @POST public Navigation execute(WebContext context) { String hoge = context.getRequest().getAttribute("hoge"); return Json.convert(hoge + " is jQuery."); } } HTTP ヘッダで Ajax のリクエストを判別 16. @Ajax を使ったサンプル(2) 【 jQuery 】 $(funcion() { $("#submit").click(function() { $.ajax( { "url" : " {cx}/ajaxJQuery/execute ", "type" : " post ", "data" : { "hoge" : $("#hoge").val() }, "success" : function(response) { var o = eval("(" + response + ")"); $("#foo").text(o); }, "error": function(xmlHttpReq, status, e) { $("#foo").text("error"); } } ); return false; } ); }); メソッドアノテーション メソッドアノテーション 17. メソッドアノテーション @Amf を使ったサンプル(1) @Page("amftest") public class AmfTestPage { @Amf public Navigation findAll() { List<Bar> ret = new ArrayList<Bar>(); ・・・ return AmfResponse.to(ret); } } 18. メソッドアノテーション @Amf を使ったサンプル (2) 【 AS 】 <mx:RemoteObject id="remote" destination=" amftest " endpoint="t2.amf"/> ~ public function creationCompleteHandler(e:FlexEvent): void { document.button.addEventListener(MouseEvent.CLICK, function(e:MouseEvent): void { var token:AsyncToken = document.remote. findAll (); token.addResponder(new AsyncResponder(resultHandler, faultHandler)); }); } public function resultHandler(e:ResultEvent, o:Object=null): void { var bar:ArrayCollection = e.result as ArrayCollection; ・・・ } public function faultHandler(e:FaultEvent, o:Object=null): void { Alert.show("error : " + e.message); } endpoint 属性は特に指定はない 19. メソッドアノテーション @Amf T2 の AMF 通信は AMF3 かつ リモーティング に限定 Messaging( データプッシュ ) などもしたい場合は BlazeDS を使用 AmfContext の切り替えはクラスパス上に blazeds のクラスがあるかどうか BlazeDS を使う時は blazeds-common.jar blazeds-core.jar および設定が必要だよ! 21. 引数アノテーション とは? リクエストパラメータなどといった特定の値を引数アノテーションによって取得します 引数 アノテーションに適切なパラメータ名を書いておけば、 T2 が自動的にセットしてくれます @Page("requestparam") public class RequestParamPage { @GET @Ajax public Navigation execute( @RequestParam("ff") String foo, @RequestParam("bb") String bar) { return Json.convert( new String[] { foo, bar }); } } } 23. @RequestParam 引数アノテーション リクエスト内にある特定のパラメータを取得することができる @Page("requestparam") public class RequestParamPage { @GET @Ajax public Navigation execute( @RequestParam("ff") String foo, @RequestParam("bb") String bar) { return Json.convert( new String[] { foo, bar }); } } } 24. 引数アノテーション @Request Header リクエスト内 のヘッダーを取得することができる @Page("/requestheader") public class RequestHeaderPage { @POST @ActionParam public Navigation execute1( @RequestHeader Map<String,String> map , WebContext context) { } @POST @ActionParam public Navigation execute2( @RequestHeader(key = "content-type") String header , WebContext context) { } } 25. 引数アノテーション @SessionAttr セッション内の指定した属性の値を取得することができる @Page("session") public class SessionPage { @POST @ActionParam public Navigation message( @SessionAttr("msg1") String message1, @SessionAttr("msg2", nullable = false ) String message2, WebContext context) { Request request = context.getRequest(); Session session = context.getSession(); request.setAttribute("message1", message1); request.setAttribute("message2", message2); return Forward.to("/jsp/sessionAttr.jsp"); } } nullable 属性を false にすると例外が発生し、 このメソッドは呼び出されません 26. 引数アノテーション @Upload ファイルがアップロードされたときに、明示的にどのファイルかを指定できる @Page("upload") public class UploadPage { @POST @ActionParam public Navigation upload( @Upload("ff") UploadFile file, HttpServletRequest request) { System.out.println("file:" + file.getName()); System.out.println("size:" + file.getSize()); System.out.println(file.getContentType()); request.setAttribute(file.getName() + " is uploaded."); return Forward.to("/jsp/upload.jsp"); } } 27. @Form @Form は、サブミットされた FORM の値全てを Java のオブジェクトに マッピングしてもらうためのアノテーションです 引数アノテーション @Page("/form") public class FormPage { @POST @ActionParam public Navigation withForm( @Form AddForm dto , WebContext context, ErrorInfo errorInfo) { Request request = context.getRequest(); if (errorInfo.hasError()) { request.setAttribute("message",Constants.ERR_MSG); return Forward.to("jsp/error.jsp"); } request.setAttribute("result","success"); return Forward.to("/jsp/form.jsp"); } } <input type=“submit” name=“withForm” ~ 28. ForEach のインデックス値を取得することができます 引数アノテーション @Page("/foreach") public class ForeachPage { @POST @ActionParam("hoge[{index}]") public Navigation hoge( @Index int id , WebContext context) { final Integer i = Integer.valueOf(id); context.getRequest().setAttribute("msg", String.valueOf(i.intValue() + 1) + " submitted."); return Forward.to("/jsp/foreach.jsp"); } } 引数の型は int または Integer である必要がある @Index 30. URL の一部を引数として受け取る事ができます 引数アノテーション @Var @Page("hoge") public class VarPage { @Default @ActionPath("{foo}") public Navigation index( @Var("foo") String foo) { return NoOperation.noOp(); } @GET @ActionPath(“piyo/{foo}") public Navigation var( @Var("foo") String foo) { return NoOperation.noOp(); } } ex) http://domain/cx/hoge/ 123 ex) http://domain/cx/hoge/piyo/ 123 31. Page に対しても @Var を使用することもできます 引数アノテーション @Var @Page("/var/{aaa}/{bbb}") public class VarPage { @Default @GET public Navigation index( @Var("aaa") String string, @Var("bbb") String bbb, Request request) { System.out.println("VarPage.index() called"); System.out.println("VarPage.aaa:" + string); System.out.println("VarPage.bbb:" + bbb); request.setAttribute("var", string + " from " + bbb); return Forward.to("/jsp/var.jsp"); } } ex) http://domain/cx/var/ 123/456 33. 引数の型 HttpServletRequest , HttpServletResponse, HttpSession ServletContext Cookie/Cookie[] WebContext Request, Response UploadFile ErrorInfo 34. HttpServletRequest 引数の型 @Page("/request") public class RequestPage { @POST @ActionParam public Navigation message( HttpServletRequest request) { request.setAttribute("hello", "Hello."); return Forward.to("/jsp/request.jsp"); } } サーブレットリクエスト 36. WebContext T2 のコンテキストオブジェクト。リクエストやレスポンスを丸ごと持つ T2 内部のコンテキストも含まれる 引数の型 @Page("context") public class ContextPage { @Default public Navigation index( WebContext context ) { Request request = context.getRequest(); request.setAttribute("message", "hogehoge"); return Forward.to("/jsp/context.jsp"); } } 37. 引数の型 UploadFile アップロードされたファイルを取得することができます @Page("upload") public class UploadPage { @POST @ActionParam public Navigation upload( UploadFile file, HttpServletRequest request) { System.out.println("file:" + file.getName()); System.out.println("size:" + file.getSize()); System.out.println(file.getContentType()); request.setAttribute(file.getName() + " is uploaded."); return Forward.to("/jsp/upload.jsp"); } } 38. UploadFile 引数の型 アップロードされたファイルを配列で取得することもできます @Page("upload") public class UploadPage { @POST @ActionParam public Navigation upload( UploadFile[] files) { for (UploadFile file : files) { System.out.println("file:" + file.getName()); System.out.println("size:" + file.getSize()); System.out.println(file.getContentType()); } return Forward.to("/jsp/upload.jsp"); } } 39. 引数の型 ErrorInfo @Form 使用時型があわないなどの変換エラーが発生した場合、その値は null のままになります @Form で変換エラーが出たときの情報を ErrorInfo が保持します @Page("/hoge") public class HogePage { @POST @ActionParam public Navigation addWithForm( @Form inputForm dto, WebContext context, ErrorInfo errorInfo ) { Request request = context.getRequest(); if (errorInfo.hasError()) { request.setAttribute("msg", Constants.ERR_MSG); return Forward.to("jsp/input.jsp"); } return Forward.to("/jsp/result.jsp"); } } 40. T2 をはじめよう! 手順 1. T2core.jar と依存 Jar 2. DI コンテナに必要な Jar と依存 Jar 3. ORM に必要な Jar... 4.ディレクトリ構成は ... 43. Vili (ヴィリ)って? ・ Eclipse プラグインによるプロジェクト作成支援 ・プロジェクトの雛形(スケルトン)を生成 ・スケルトンは Maven のアーティファクトとして管理 ・フラグメントを定義することで Vili で作成したプロジェクトに 後から機能の追加もできる T2 をはじめよう! 48. T2 をはじめよう! T2 + Gaelyk の下準備 ・ Eclipse 3.5 ・ Groovy ・ GAE/J SDK ・ Eclipse Plugin (GAE/J 、 Groovy) Google Plugin for Eclipse http://code.google.com/intl/ja/eclipse/docs/getting_started.html GroovyEclipse Plugin http://groovy.codehaus.org/Install+GroovyEclipse+Plugin 49. T2 をはじめよう! T2 + Gaelyk のセットアップ 1. T2MeetsGaelykSetup.groovy を DL 2.ダウンロードしたスクリプトを実行する 3. Eclipse にインポート 50. T2 をはじめよう! T2 + Gaelyk のセットアップ 1. T2MeetsGaelykSetup.groovy を DL 以下の URL から T2MeetsGaelykSetup.groovy をダウンロードする http://code.google.com/p/t2samples/downloads/list 51. T2 + Gaelyk のセットアップ 2.ダウンロードしたスクリプトを実行する T2 をはじめよう! groovy T2MeetsGaelykSetup.groovy プロジェクト名 52. T2 + Gaelyk のセットアップ 3. Eclipse にインポート Eclipse のファイルメニューから以下の順で選択していく T2 をはじめよう! File -> Import Existing Projects into Workspace Select root directory -> Browse -> Finish Package Explorer からプロジェクト名を右クリック -> Run As -> Web Application 実行 53. まとめ メリット 敷居はそんなに低くない ・わかりやすい ・機能が絞られている ・プロジェクト生成プラグインがある Ajax 、 AMF 通信するときに気軽に使える ・追加で必要な jar や設定がない ・通常のリクエストと区別できる デメリット 単体で使うには機能が少ない ・ t2-ext もしくは誰かが作ったものが充実する必要がある 実績が比較的少ない ・使用ユーザーの介入が不可欠 55. T2 プロジェクト T2 プロジェクト http://code.google.com/p/t-2/ Committer shot6 http://d.hatena.ne.jp/shot6/ skirnir http://d.hatena.ne.jp/skirnir / c9katayama http://d.hatena.ne.jp/c9katayama/ yone098 h ttp://d.hatena.ne.jp/yone098/