Copyright  2010  The Team T2 Framework and the others All Rights Reserved. つなぐ、つながる、つないでなんぼ! Web フレームワーク 「 T2 」 の紹介 Go Tanaka <tanago3@gmail.com>
自己紹介 田中 豪    ( たなか ごう ) Blog: http://d.hatena.ne.jp/tan_go238/ Twitter: http://twitter.com/tan_go238/
「T2」って何? 他のフレームワークと「つなげて」使うことを前提としたフレームワーク 特徴 リクエストをかしこく捌く! つなぐ、つながる! シンプルでわかりやすい!
シンプルで分かりやすい アノテーションベース @Page(“/hello”) public   class  Hoge { @GET @ActionPath(“/world”) public  Navigation helloWorld(){  … } } http://yoursite.com/app/ hello / world きれいな URL!
そもそも、そんなにたくさんの機能はない シンプルで分かりやすい DI コンテナ (シンプルな内部コンテナをデフォルトで使用) DB フレームワーク Validation フレームワーク トランザクション制御 (  t2-ext  にもある) 自分の使いやすいものを使ってね!
つなぐ、つながる! 自分の使いやすいものをつなげて使おう! DI コンテナ   Seasar,  Spring,  Guice, Lucy,  内部 DI コンテナ OR マッパー   S2Dao, DBFlute, Doma, Hibernate, iBatis テンプレートエンジン   JSP, ZPT, Mayaa...  サンプルもいっぱいあるよ!
リクエストをかしこく捌く! 様々なリクエスト対応したメソッドを呼び出せる! AMF や Ajax のリクエストが捌ける URL パス や リクエストパラメータ で切り替えができる GET や POST でメソッドの切り替えができる レスポンスの種類も色々あるよ!
機能紹介 メソッドアノテーション 引数アノテーション 引数の型 T2 の基本的な使い方は以下の3つをおさえておけばOK!
メソッドアノテーション とは? リクエストとメソッドのマッピング を行います @Page(“/hello”) public   class  Hoge { @GET @ActionPath(“/world”) public  Navigation helloWorld(){  … } } 順番も重要
メソッドアノテーション とは? @GET, @POST @ActionPath @ActionParam @Ajax @Amf @Default メソッドアノテーション一覧
@GET と @ActionPath を使ったサンプル メソッドアノテーション @Page(“/hello”) public   class  Hoge { @GET @ActionPath(“/world”) public  Navigation helloWorld(){  … } } http://yoursite.com/app/ hello / world
メソッドアノテーション @Page(“/hello”) public   class  Hoge { @POST @ActionParam public  Navigation  add (WebContext context){  … } } @POST と @ActionParam を使ったサンプル <form name=&quot;addForm&quot; action=&quot; /{cx}/hello ”   method=&quot; post &quot;> <input type=&quot;text&quot; name=&quot;arg1&quot; /><br /> <input type=&quot;submit&quot; name=&quot; add &quot; value=&quot; 送信 &quot;/> </form> @ActionParam だけだと メソッド名=ボタンの name 属性 と認識
@ActionParam @ActionParam はサブミットされたボタンを認識するためのアノテーション @ActionParam(&quot;hoge&quot;) のように書いている場合、 hoge という name 属性を持つボタンが押されたときに動きます メソッドアノテーション @Page(“/hello”) public   class  Hoge { @ POST @ActionParam(“hoge”) public  Navigation foo(WebContext context){  … } }
@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”  ~
@Ajax を使ったサンプル(1) メソッドアノテーション @Page(&quot;/ajaxJQuery&quot;) public   class  AjaxJQueryPage { @Ajax @POST public  Navigation execute(WebContext context) {      String hoge = context.getRequest().getAttribute(&quot;hoge&quot;); return Json.convert(hoge + &quot; is jQuery.&quot;); } } HTTP ヘッダで Ajax のリクエストを判別
@Ajax を使ったサンプル(2) 【 jQuery 】 $(funcion() { $(&quot;#submit&quot;).click(function() { $.ajax(  { &quot;url&quot; : &quot; {cx}/ajaxJQuery/execute &quot;, &quot;type&quot; : &quot; post &quot;, &quot;data&quot;  : { &quot;hoge&quot; : $(&quot;#hoge&quot;).val() }, &quot;success&quot; : function(response) { var o = eval(&quot;(&quot; + response + &quot;)&quot;); $(&quot;#foo&quot;).text(o); }, &quot;error&quot;: function(xmlHttpReq, status, e) { $(&quot;#foo&quot;).text(&quot;error&quot;); } } ); return false; } ); }); メソッドアノテーション メソッドアノテーション
メソッドアノテーション @Amf を使ったサンプル(1) @Page(&quot;amftest&quot;) public   class  AmfTestPage { @Amf public  Navigation findAll() { List<Bar> ret = new ArrayList<Bar>(); ・・・ return AmfResponse.to(ret); } }
メソッドアノテーション @Amf を使ったサンプル (2) 【 AS 】 <mx:RemoteObject id=&quot;remote&quot; destination=&quot; amftest &quot; endpoint=&quot;t2.amf&quot;/> ~  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(&quot;error : &quot; + e.message); } endpoint 属性は特に指定はない
メソッドアノテーション @Amf T2 の AMF 通信は AMF3 かつ リモーティング に限定  Messaging( データプッシュ ) などもしたい場合は  BlazeDS   を使用 AmfContext  の切り替えはクラスパス上に blazeds のクラスがあるかどうか BlazeDS を使う時は blazeds-common.jar blazeds-core.jar  および設定が必要だよ!
どのメソッドの条件にも該当しなかった場合、 @Default がついたメソッドが呼び出されます メソッドアノテーション @Default Page(&quot;hoge&quot;) public   class  HogePage { @Default public  Navigation index() { return Forward.to(&quot;/jsp/index.jsp&quot;); } }
引数アノテーション とは? リクエストパラメータなどといった特定の値を引数アノテーションによって取得します 引数 アノテーションに適切なパラメータ名を書いておけば、 T2 が自動的にセットしてくれます @Page(&quot;requestparam&quot;) public   class  RequestParamPage { @GET @Ajax public  Navigation execute( @RequestParam(&quot;ff&quot;)  String foo, @RequestParam(&quot;bb&quot;)  String bar) { return  Json.convert( new String[] { foo, bar }); } } }
引数アノテーション @RequestParam @RequestHeader @SessionAttr @Upload @Form @Index @Var 引数アノテーション一覧
@RequestParam 引数アノテーション リクエスト内にある特定のパラメータを取得することができる @Page(&quot;requestparam&quot;) public   class  RequestParamPage { @GET @Ajax public  Navigation execute( @RequestParam(&quot;ff&quot;)  String foo, @RequestParam(&quot;bb&quot;)  String bar) { return  Json.convert( new String[] { foo, bar }); } } }
引数アノテーション @Request Header リクエスト内 のヘッダーを取得することができる @Page(&quot;/requestheader&quot;) public   class  RequestHeaderPage { @POST @ActionParam public  Navigation execute1( @RequestHeader Map<String,String> map , WebContext context) { } @POST @ActionParam public  Navigation execute2(         @RequestHeader(key = &quot;content-type&quot;)   String header , WebContext context) { } }
引数アノテーション @SessionAttr セッション内の指定した属性の値を取得することができる @Page(&quot;session&quot;) public   class  SessionPage { @POST @ActionParam public  Navigation message( @SessionAttr(&quot;msg1&quot;)  String message1,  @SessionAttr(&quot;msg2&quot;,  nullable = false )  String message2, WebContext context) { Request request = context.getRequest(); Session session = context.getSession(); request.setAttribute(&quot;message1&quot;, message1); request.setAttribute(&quot;message2&quot;, message2); return  Forward.to(&quot;/jsp/sessionAttr.jsp&quot;); } } nullable 属性を false にすると例外が発生し、 このメソッドは呼び出されません
引数アノテーション @Upload ファイルがアップロードされたときに、明示的にどのファイルかを指定できる @Page(&quot;upload&quot;) public   class  UploadPage   { @POST @ActionParam public  Navigation upload( @Upload(&quot;ff&quot;)  UploadFile file, HttpServletRequest request) { System.out.println(&quot;file:&quot; + file.getName()); System.out.println(&quot;size:&quot; + file.getSize()); System.out.println(file.getContentType()); request.setAttribute(file.getName() + &quot; is uploaded.&quot;); return  Forward.to(&quot;/jsp/upload.jsp&quot;); } }
@Form @Form は、サブミットされた FORM の値全てを Java のオブジェクトに マッピングしてもらうためのアノテーションです 引数アノテーション @Page(&quot;/form&quot;) public   class  FormPage { @POST @ActionParam public  Navigation withForm(  @Form AddForm dto ,  WebContext context, ErrorInfo errorInfo) { Request request = context.getRequest(); if (errorInfo.hasError()) { request.setAttribute(&quot;message&quot;,Constants.ERR_MSG); return  Forward.to(&quot;jsp/error.jsp&quot;); } request.setAttribute(&quot;result&quot;,&quot;success&quot;); return  Forward.to(&quot;/jsp/form.jsp&quot;); } } <input type=“submit” name=“withForm”  ~
ForEach のインデックス値を取得することができます 引数アノテーション @Page(&quot;/foreach&quot;) public   class  ForeachPage { @POST @ActionParam(&quot;hoge[{index}]&quot;) public  Navigation hoge( @Index int id , WebContext context) { final Integer i = Integer.valueOf(id); context.getRequest().setAttribute(&quot;msg&quot;, String.valueOf(i.intValue() + 1) + &quot; submitted.&quot;); return Forward.to(&quot;/jsp/foreach.jsp&quot;); } } 引数の型は  int  または  Integer  である必要がある @Index
<form method=&quot;post&quot; action=&quot;${t:url('/foreach')}&quot;> <c:forEach var=&quot;e&quot; items=&quot;${hogeList}&quot; varStatus=&quot;s&quot;> <input type=&quot;submit&quot; name=&quot; hoge[${s.index}] &quot; value=&quot;${e}&quot;/> <br /> </c:forEach> <span>${message}</span> </form> HTML側 (JSP) の記述 引数アノテーション @Index
URL の一部を引数として受け取る事ができます 引数アノテーション @Var @Page(&quot;hoge&quot;) public   class  VarPage { @Default @ActionPath(&quot;{foo}&quot;) public  Navigation index( @Var(&quot;foo&quot;)  String foo) { return  NoOperation.noOp(); } @GET @ActionPath(“piyo/{foo}&quot;) public  Navigation var( @Var(&quot;foo&quot;)  String foo) { return  NoOperation.noOp(); } } ex) http://domain/cx/hoge/ 123 ex) http://domain/cx/hoge/piyo/ 123
Page に対しても  @Var  を使用することもできます 引数アノテーション @Var @Page(&quot;/var/{aaa}/{bbb}&quot;) public   class  VarPage { @Default @GET public  Navigation index( @Var(&quot;aaa&quot;)  String string,  @Var(&quot;bbb&quot;)  String bbb, Request request) { System.out.println(&quot;VarPage.index() called&quot;); System.out.println(&quot;VarPage.aaa:&quot; + string); System.out.println(&quot;VarPage.bbb:&quot; + bbb); request.setAttribute(&quot;var&quot;, string + &quot; from &quot; + bbb); return  Forward.to(&quot;/jsp/var.jsp&quot;); } } ex) http://domain/cx/var/ 123/456
引数の型 欲しいインスタンスをメソッドの引数によって取得します 引数に適切なオブジェクトを書いておけば、 T2 が自動的にセットしてくれます public  Navigation add(HttpServletRequest request, HttpServletResponseresponse) 使用したいオブジェクトを引数に指定するだけ
引数の型 HttpServletRequest , HttpServletResponse,  HttpSession ServletContext Cookie/Cookie[] WebContext Request, Response UploadFile ErrorInfo
HttpServletRequest 引数の型 @Page(&quot;/request&quot;) public   class  RequestPage { @POST @ActionParam public  Navigation message( HttpServletRequest  request) { request.setAttribute(&quot;hello&quot;, &quot;Hello.&quot;); return  Forward.to(&quot;/jsp/request.jsp&quot;); } } サーブレットリクエスト
引数の型 ServletContext @Page(&quot;/hoge&quot;) public   class  Hoge { @Default public  Navigation index( ServletContext  context) { ・・・ } } サーブレットコンテキスト
WebContext T2 のコンテキストオブジェクト。リクエストやレスポンスを丸ごと持つ T2 内部のコンテキストも含まれる 引数の型 @Page(&quot;context&quot;) public   class  ContextPage { @Default public  Navigation index( WebContext context ) { Request request = context.getRequest(); request.setAttribute(&quot;message&quot;, &quot;hogehoge&quot;); return  Forward.to(&quot;/jsp/context.jsp&quot;); } }
引数の型 UploadFile アップロードされたファイルを取得することができます @Page(&quot;upload&quot;) public   class  UploadPage { @POST @ActionParam public  Navigation upload( UploadFile  file,  HttpServletRequest request) { System.out.println(&quot;file:&quot; + file.getName()); System.out.println(&quot;size:&quot; + file.getSize()); System.out.println(file.getContentType()); request.setAttribute(file.getName() + &quot; is uploaded.&quot;); return  Forward.to(&quot;/jsp/upload.jsp&quot;); } }
UploadFile 引数の型 アップロードされたファイルを配列で取得することもできます @Page(&quot;upload&quot;) public   class  UploadPage { @POST @ActionParam public  Navigation upload( UploadFile[]  files) { for (UploadFile file : files) { System.out.println(&quot;file:&quot; + file.getName()); System.out.println(&quot;size:&quot; + file.getSize()); System.out.println(file.getContentType()); } return  Forward.to(&quot;/jsp/upload.jsp&quot;); } }
引数の型 ErrorInfo @Form 使用時型があわないなどの変換エラーが発生した場合、その値は null のままになります @Form で変換エラーが出たときの情報を  ErrorInfo  が保持します @Page(&quot;/hoge&quot;) public   class  HogePage { @POST @ActionParam public  Navigation addWithForm( @Form inputForm dto, WebContext context,  ErrorInfo errorInfo ) { Request request = context.getRequest(); if (errorInfo.hasError()) { request.setAttribute(&quot;msg&quot;, Constants.ERR_MSG); return  Forward.to(&quot;jsp/input.jsp&quot;); } return  Forward.to(&quot;/jsp/result.jsp&quot;); } }
T2 をはじめよう! 手順 1. T2core.jar と依存 Jar 2. DI コンテナに必要な Jar と依存 Jar 3. ORM に必要な Jar... 4.ディレクトリ構成は ...
T2 をはじめよう! 何?めんどくさい??
T2 をはじめよう! Vili (ヴィリ)があるよ!!
Vili (ヴィリ)って? ・ Eclipse プラグインによるプロジェクト作成支援 ・プロジェクトの雛形(スケルトン)を生成 ・スケルトンは Maven のアーティファクトとして管理 ・フラグメントを定義することで Vili で作成したプロジェクトに  後から機能の追加もできる T2 をはじめよう!
T2 をはじめよう! 引用元: http://d.hatena.ne.jp/skirnir/20091021/1256105886
T2 をはじめよう! 引用元: http://d.hatena.ne.jp/skirnir/20091021/1256105886
T2 をはじめよう! Gaelyk もやりたい?
あるよ!! T2 をはじめよう!
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
T2 をはじめよう! T2 + Gaelyk のセットアップ 1. T2MeetsGaelykSetup.groovy  を DL 2.ダウンロードしたスクリプトを実行する 3. Eclipse にインポート
T2 をはじめよう! T2 + Gaelyk のセットアップ 1. T2MeetsGaelykSetup.groovy  を DL 以下の URL から  T2MeetsGaelykSetup.groovy  をダウンロードする   http://code.google.com/p/t2samples/downloads/list
T2 + Gaelyk のセットアップ 2.ダウンロードしたスクリプトを実行する T2 をはじめよう! groovy T2MeetsGaelykSetup.groovy  プロジェクト名
T2 + Gaelyk のセットアップ 3. Eclipse にインポート Eclipse のファイルメニューから以下の順で選択していく T2 をはじめよう! File -> Import Existing Projects into Workspace Select root directory -> Browse -> Finish  Package Explorer からプロジェクト名を右クリック  -> Run As -> Web Application  実行
まとめ メリット   敷居はそんなに低くない     ・わかりやすい     ・機能が絞られている     ・プロジェクト生成プラグインがある    Ajax 、 AMF 通信するときに気軽に使える     ・追加で必要な jar や設定がない     ・通常のリクエストと区別できる    デメリット   単体で使うには機能が少ない     ・ t2-ext もしくは誰かが作ったものが充実する必要がある   実績が比較的少ない     ・使用ユーザーの介入が不可欠
まとめ ・もっとプラグインが充実して欲しい! ・もっとサンプルが充実して欲しい! ・もっと使ってくれるユーザーが欲しい! みんながどんどん使っていくと、面白いぐらい進化しそう! 実はプラグインなど拡張するための仕組みも充実
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/
T2 プロジェクト designed by  カネウチカズコ
ご清聴ありがとうございました!!

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/
  • 3.
    「T2」って何? 他のフレームワークと「つなげて」使うことを前提としたフレームワーク 特徴リクエストをかしこく捌く! つなぐ、つながる! シンプルでわかりやすい!
  • 4.
    シンプルで分かりやすい アノテーションベース @Page(“/hello”)public class Hoge { @GET @ActionPath(“/world”) public Navigation helloWorld(){ … } } http://yoursite.com/app/ hello / world きれいな URL!
  • 5.
    そもそも、そんなにたくさんの機能はない シンプルで分かりやすい DIコンテナ (シンプルな内部コンテナをデフォルトで使用) DB フレームワーク Validation フレームワーク トランザクション制御 ( t2-ext にもある) 自分の使いやすいものを使ってね!
  • 6.
    つなぐ、つながる! 自分の使いやすいものをつなげて使おう! DIコンテナ   Seasar, Spring, Guice, Lucy, 内部 DI コンテナ OR マッパー   S2Dao, DBFlute, Doma, Hibernate, iBatis テンプレートエンジン   JSP, ZPT, Mayaa... サンプルもいっぱいあるよ!
  • 7.
    リクエストをかしこく捌く! 様々なリクエスト対応したメソッドを呼び出せる! AMFや Ajax のリクエストが捌ける URL パス や リクエストパラメータ で切り替えができる GET や POST でメソッドの切り替えができる レスポンスの種類も色々あるよ!
  • 8.
    機能紹介 メソッドアノテーション 引数アノテーション引数の型 T2 の基本的な使い方は以下の3つをおさえておけばOK!
  • 9.
    メソッドアノテーション とは? リクエストとメソッドのマッピングを行います @Page(“/hello”) public class Hoge { @GET @ActionPath(“/world”) public Navigation helloWorld(){ … } } 順番も重要
  • 10.
    メソッドアノテーション とは? @GET,@POST @ActionPath @ActionParam @Ajax @Amf @Default メソッドアノテーション一覧
  • 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=&quot;addForm&quot; action=&quot; /{cx}/hello ” method=&quot; post &quot;> <input type=&quot;text&quot; name=&quot;arg1&quot; /><br /> <input type=&quot;submit&quot; name=&quot; add &quot; value=&quot; 送信 &quot;/> </form> @ActionParam だけだと メソッド名=ボタンの name 属性 と認識
  • 13.
    @ActionParam @ActionParam はサブミットされたボタンを認識するためのアノテーション@ActionParam(&quot;hoge&quot;) のように書いている場合、 hoge という name 属性を持つボタンが押されたときに動きます メソッドアノテーション @Page(“/hello”) public class Hoge { @ POST @ActionParam(“hoge”) public Navigation foo(WebContext context){ … } }
  • 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(&quot;/ajaxJQuery&quot;) public class AjaxJQueryPage { @Ajax @POST public Navigation execute(WebContext context) {      String hoge = context.getRequest().getAttribute(&quot;hoge&quot;); return Json.convert(hoge + &quot; is jQuery.&quot;); } } HTTP ヘッダで Ajax のリクエストを判別
  • 16.
    @Ajax を使ったサンプル(2) 【jQuery 】 $(funcion() { $(&quot;#submit&quot;).click(function() { $.ajax( { &quot;url&quot; : &quot; {cx}/ajaxJQuery/execute &quot;, &quot;type&quot; : &quot; post &quot;, &quot;data&quot; : { &quot;hoge&quot; : $(&quot;#hoge&quot;).val() }, &quot;success&quot; : function(response) { var o = eval(&quot;(&quot; + response + &quot;)&quot;); $(&quot;#foo&quot;).text(o); }, &quot;error&quot;: function(xmlHttpReq, status, e) { $(&quot;#foo&quot;).text(&quot;error&quot;); } } ); return false; } ); }); メソッドアノテーション メソッドアノテーション
  • 17.
    メソッドアノテーション @Amf を使ったサンプル(1)@Page(&quot;amftest&quot;) public class AmfTestPage { @Amf public Navigation findAll() { List<Bar> ret = new ArrayList<Bar>(); ・・・ return AmfResponse.to(ret); } }
  • 18.
    メソッドアノテーション @Amf を使ったサンプル(2) 【 AS 】 <mx:RemoteObject id=&quot;remote&quot; destination=&quot; amftest &quot; endpoint=&quot;t2.amf&quot;/> ~ 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(&quot;error : &quot; + e.message); } endpoint 属性は特に指定はない
  • 19.
    メソッドアノテーション @Amf T2の AMF 通信は AMF3 かつ リモーティング に限定 Messaging( データプッシュ ) などもしたい場合は BlazeDS を使用 AmfContext の切り替えはクラスパス上に blazeds のクラスがあるかどうか BlazeDS を使う時は blazeds-common.jar blazeds-core.jar および設定が必要だよ!
  • 20.
    どのメソッドの条件にも該当しなかった場合、 @Default がついたメソッドが呼び出されますメソッドアノテーション @Default Page(&quot;hoge&quot;) public class HogePage { @Default public Navigation index() { return Forward.to(&quot;/jsp/index.jsp&quot;); } }
  • 21.
    引数アノテーション とは? リクエストパラメータなどといった特定の値を引数アノテーションによって取得します引数 アノテーションに適切なパラメータ名を書いておけば、 T2 が自動的にセットしてくれます @Page(&quot;requestparam&quot;) public class RequestParamPage { @GET @Ajax public Navigation execute( @RequestParam(&quot;ff&quot;) String foo, @RequestParam(&quot;bb&quot;) String bar) { return Json.convert( new String[] { foo, bar }); } } }
  • 22.
    引数アノテーション @RequestParam @RequestHeader@SessionAttr @Upload @Form @Index @Var 引数アノテーション一覧
  • 23.
    @RequestParam 引数アノテーション リクエスト内にある特定のパラメータを取得することができる@Page(&quot;requestparam&quot;) public class RequestParamPage { @GET @Ajax public Navigation execute( @RequestParam(&quot;ff&quot;) String foo, @RequestParam(&quot;bb&quot;) String bar) { return Json.convert( new String[] { foo, bar }); } } }
  • 24.
    引数アノテーション @Request Headerリクエスト内 のヘッダーを取得することができる @Page(&quot;/requestheader&quot;) public class RequestHeaderPage { @POST @ActionParam public Navigation execute1( @RequestHeader Map<String,String> map , WebContext context) { } @POST @ActionParam public Navigation execute2(         @RequestHeader(key = &quot;content-type&quot;) String header , WebContext context) { } }
  • 25.
    引数アノテーション @SessionAttr セッション内の指定した属性の値を取得することができる@Page(&quot;session&quot;) public class SessionPage { @POST @ActionParam public Navigation message( @SessionAttr(&quot;msg1&quot;) String message1, @SessionAttr(&quot;msg2&quot;, nullable = false ) String message2, WebContext context) { Request request = context.getRequest(); Session session = context.getSession(); request.setAttribute(&quot;message1&quot;, message1); request.setAttribute(&quot;message2&quot;, message2); return Forward.to(&quot;/jsp/sessionAttr.jsp&quot;); } } nullable 属性を false にすると例外が発生し、 このメソッドは呼び出されません
  • 26.
    引数アノテーション @Upload ファイルがアップロードされたときに、明示的にどのファイルかを指定できる@Page(&quot;upload&quot;) public class UploadPage { @POST @ActionParam public Navigation upload( @Upload(&quot;ff&quot;) UploadFile file, HttpServletRequest request) { System.out.println(&quot;file:&quot; + file.getName()); System.out.println(&quot;size:&quot; + file.getSize()); System.out.println(file.getContentType()); request.setAttribute(file.getName() + &quot; is uploaded.&quot;); return Forward.to(&quot;/jsp/upload.jsp&quot;); } }
  • 27.
    @Form @Form は、サブミットされたFORM の値全てを Java のオブジェクトに マッピングしてもらうためのアノテーションです 引数アノテーション @Page(&quot;/form&quot;) public class FormPage { @POST @ActionParam public Navigation withForm( @Form AddForm dto , WebContext context, ErrorInfo errorInfo) { Request request = context.getRequest(); if (errorInfo.hasError()) { request.setAttribute(&quot;message&quot;,Constants.ERR_MSG); return Forward.to(&quot;jsp/error.jsp&quot;); } request.setAttribute(&quot;result&quot;,&quot;success&quot;); return Forward.to(&quot;/jsp/form.jsp&quot;); } } <input type=“submit” name=“withForm” ~
  • 28.
    ForEach のインデックス値を取得することができます 引数アノテーション@Page(&quot;/foreach&quot;) public class ForeachPage { @POST @ActionParam(&quot;hoge[{index}]&quot;) public Navigation hoge( @Index int id , WebContext context) { final Integer i = Integer.valueOf(id); context.getRequest().setAttribute(&quot;msg&quot;, String.valueOf(i.intValue() + 1) + &quot; submitted.&quot;); return Forward.to(&quot;/jsp/foreach.jsp&quot;); } } 引数の型は int または Integer である必要がある @Index
  • 29.
    <form method=&quot;post&quot; action=&quot;${t:url('/foreach')}&quot;><c:forEach var=&quot;e&quot; items=&quot;${hogeList}&quot; varStatus=&quot;s&quot;> <input type=&quot;submit&quot; name=&quot; hoge[${s.index}] &quot; value=&quot;${e}&quot;/> <br /> </c:forEach> <span>${message}</span> </form> HTML側 (JSP) の記述 引数アノテーション @Index
  • 30.
    URL の一部を引数として受け取る事ができます 引数アノテーション@Var @Page(&quot;hoge&quot;) public class VarPage { @Default @ActionPath(&quot;{foo}&quot;) public Navigation index( @Var(&quot;foo&quot;) String foo) { return NoOperation.noOp(); } @GET @ActionPath(“piyo/{foo}&quot;) public Navigation var( @Var(&quot;foo&quot;) String foo) { return NoOperation.noOp(); } } ex) http://domain/cx/hoge/ 123 ex) http://domain/cx/hoge/piyo/ 123
  • 31.
    Page に対しても @Var を使用することもできます 引数アノテーション @Var @Page(&quot;/var/{aaa}/{bbb}&quot;) public class VarPage { @Default @GET public Navigation index( @Var(&quot;aaa&quot;) String string, @Var(&quot;bbb&quot;) String bbb, Request request) { System.out.println(&quot;VarPage.index() called&quot;); System.out.println(&quot;VarPage.aaa:&quot; + string); System.out.println(&quot;VarPage.bbb:&quot; + bbb); request.setAttribute(&quot;var&quot;, string + &quot; from &quot; + bbb); return Forward.to(&quot;/jsp/var.jsp&quot;); } } ex) http://domain/cx/var/ 123/456
  • 32.
    引数の型 欲しいインスタンスをメソッドの引数によって取得します 引数に適切なオブジェクトを書いておけば、T2 が自動的にセットしてくれます public Navigation add(HttpServletRequest request, HttpServletResponseresponse) 使用したいオブジェクトを引数に指定するだけ
  • 33.
    引数の型 HttpServletRequest ,HttpServletResponse, HttpSession ServletContext Cookie/Cookie[] WebContext Request, Response UploadFile ErrorInfo
  • 34.
    HttpServletRequest 引数の型 @Page(&quot;/request&quot;)public class RequestPage { @POST @ActionParam public Navigation message( HttpServletRequest request) { request.setAttribute(&quot;hello&quot;, &quot;Hello.&quot;); return Forward.to(&quot;/jsp/request.jsp&quot;); } } サーブレットリクエスト
  • 35.
    引数の型 ServletContext @Page(&quot;/hoge&quot;)public class Hoge { @Default public Navigation index( ServletContext context) { ・・・ } } サーブレットコンテキスト
  • 36.
    WebContext T2 のコンテキストオブジェクト。リクエストやレスポンスを丸ごと持つT2 内部のコンテキストも含まれる 引数の型 @Page(&quot;context&quot;) public class ContextPage { @Default public Navigation index( WebContext context ) { Request request = context.getRequest(); request.setAttribute(&quot;message&quot;, &quot;hogehoge&quot;); return Forward.to(&quot;/jsp/context.jsp&quot;); } }
  • 37.
    引数の型 UploadFile アップロードされたファイルを取得することができます@Page(&quot;upload&quot;) public class UploadPage { @POST @ActionParam public Navigation upload( UploadFile file, HttpServletRequest request) { System.out.println(&quot;file:&quot; + file.getName()); System.out.println(&quot;size:&quot; + file.getSize()); System.out.println(file.getContentType()); request.setAttribute(file.getName() + &quot; is uploaded.&quot;); return Forward.to(&quot;/jsp/upload.jsp&quot;); } }
  • 38.
    UploadFile 引数の型 アップロードされたファイルを配列で取得することもできます@Page(&quot;upload&quot;) public class UploadPage { @POST @ActionParam public Navigation upload( UploadFile[] files) { for (UploadFile file : files) { System.out.println(&quot;file:&quot; + file.getName()); System.out.println(&quot;size:&quot; + file.getSize()); System.out.println(file.getContentType()); } return Forward.to(&quot;/jsp/upload.jsp&quot;); } }
  • 39.
    引数の型 ErrorInfo @Form使用時型があわないなどの変換エラーが発生した場合、その値は null のままになります @Form で変換エラーが出たときの情報を ErrorInfo が保持します @Page(&quot;/hoge&quot;) public class HogePage { @POST @ActionParam public Navigation addWithForm( @Form inputForm dto, WebContext context, ErrorInfo errorInfo ) { Request request = context.getRequest(); if (errorInfo.hasError()) { request.setAttribute(&quot;msg&quot;, Constants.ERR_MSG); return Forward.to(&quot;jsp/input.jsp&quot;); } return Forward.to(&quot;/jsp/result.jsp&quot;); } }
  • 40.
    T2 をはじめよう! 手順1. T2core.jar と依存 Jar 2. DI コンテナに必要な Jar と依存 Jar 3. ORM に必要な Jar... 4.ディレクトリ構成は ...
  • 41.
  • 42.
    T2 をはじめよう! Vili(ヴィリ)があるよ!!
  • 43.
    Vili (ヴィリ)って? ・Eclipse プラグインによるプロジェクト作成支援 ・プロジェクトの雛形(スケルトン)を生成 ・スケルトンは Maven のアーティファクトとして管理 ・フラグメントを定義することで Vili で作成したプロジェクトに  後から機能の追加もできる T2 をはじめよう!
  • 44.
    T2 をはじめよう! 引用元:http://d.hatena.ne.jp/skirnir/20091021/1256105886
  • 45.
    T2 をはじめよう! 引用元:http://d.hatena.ne.jp/skirnir/20091021/1256105886
  • 46.
  • 47.
  • 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 もしくは誰かが作ったものが充実する必要がある   実績が比較的少ない     ・使用ユーザーの介入が不可欠
  • 54.
    まとめ ・もっとプラグインが充実して欲しい! ・もっとサンプルが充実して欲しい!・もっと使ってくれるユーザーが欲しい! みんながどんどん使っていくと、面白いぐらい進化しそう! 実はプラグインなど拡張するための仕組みも充実
  • 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/
  • 56.
    T2 プロジェクト designedby カネウチカズコ
  • 57.