結論としては、@higayasuo さんがお話されていた通り「当たり前の挙動」を示しているだけなのかなーと。
サーブレットに詳しくない自分としてはちょっとツラい感じです
※6/9修正しました。ソース部分をasXxxを使った形に書き換え&こちらを参考にrequestなどの取得について修正
確認しました。
POSTが噛んだときの、マッピングの判断条件の考え方が間違っていました。
RequestMapのgetは、内部でHttpRequestServletのgetAttribute()を呼び出します。
で。
- Formのenctypeが「multipart/form-data」の場合
POSTがない場合はこれでGETの引数としてのマッピング先(?key={key})が取得できるのですが、POSTデータがある場合はこの値がPOSTの内容になるようです。
GETの値はどこかというと、「request.getParameter("key")」で取得できる模様
- Formのenctypeが「text/plain」の場合
RequestMapのgetは、GETの値、つまりURLマッピングの「?key={key}」が入っています。
POSTの値は・・・getParameterでも取れませんでした。
とりあえずURLマッピングを絡めてPOSTを扱う場合は、「multipart/form-data」にしておくことをオススメします。
以下修正しました。
ひと通り動く版。POSTは「multipart/form-data」で。
参照リンク
http://sites.google.com/site/slim3documentja/documents/slim3-controller/url-mapping
Slim3は通常、
というようにマッピングルールに基づいて、実行するコントローラが決まります。※slim3.rootpackage は web.xml で定義されています。
リクエストURLパス コントローラ / slim3.rootpackage.controller.IndexController /xxx slim3.rootpackage.controller.XxxController /xxx/ slim3.rootpackage.controller.xxx.IndexController /xxx/yyy slim3.rootpackage.controller.xxx.YyyController /xxx/yyy/zzz slim3.rootpackage.controller.xxx.yyy.ZzzController
リンク先に書いてあるのをちゃんと読んでいなかったのですが、このURLマッピングはある程度制御することができます
コントローラを取得する前にリクエストURLパスの書き換えをすることもできます。
URLリライティングを使うには slim3.rootpackage.controller.AppRouter クラスを先に定義する必要があります。
とのこと。実際にやってみましょう
slim3.rootpackageが「jp.tyato.test」だとすると、「jp.tyato.test.controller.AppRouter」クラスを生成します
- 「jp.tyato.test.controller」のパッケージを用意する
- 「jp.tyato.test.controller」配下に「AppRouter」クラスを生成。内容は次のような感じ
6/8修正
package jp.tyato.test.controller; import org.slim3.controller.router.RouterImpl; public class AppRouter extends RouterImpl { Public AppRouter() { addRouting("/xxx/{key}", "/xxx?key={key}"); } }
次にIndexControllerクラスを生成します
- 「build.xml」を開き、アウトラインから「gen-controller-without-view」を選択、実行から「1 Ant ビルド」を実行する
- 名前の入力を求められるので、「/xxx/Index」と入力
- 「jp.tyato.test.controller.xxx」配下に「IndexController.java」が作成される
- メソッド「run」の中を書き換える
final String KEY_NAME = "key"; @Override public Navigation run() throws Exception { Navigation result = null; try { String keyword = asString(KEY_NAME); if(keyword == null) { //getParameterで再度試行 keyword = request.getParameter(KEY_NAME); } if( keyword != null ) { keyword = keyword.toLowerCase(); } //Factoryパターン用コントローラ親クラスの定義 Controller con = this.GetFromFactory(keyword); result = con.runBare(); } catch (Throwable e) { e.printStackTrace(); } return result; } public Controller GetFromFactory(String keyword) { Controller con = null; try { if (keyword == null || keyword.isEmpty() || keyword.startsWith("index") ) { //keywordがnull、空文字、indexで始まる文字のいずれかである場合、Index表示処理 con = new ForDefaultController(); } else if (keyword.equals("yyy")) { //keyが「yyy」である場合、yyy用の処理へ con = new YyyController(); } else if (keyword.equals("zzz")) { //keyが「zzz」である場合、zzz用の処理へ con = new ZzzController(); } } catch (Exception e) { e.printStackTrace(); } return con; }後は実際に処理を行うControllerクラスを実装します。
この場合は「ForDefaultController」「YyyController」「ZzzController」について
- 「build.xml」を開き、アウトラインから「gen-controller-without-view」を選択、実行から「1 Ant ビルド」を実行する
- 名前の入力を求められるので、「/xxx/???」と入力
- 「jp.tyato.test.controller.xxx」配下に「???Controller.java」が作成される
しかしこのままですと、各Controllerを呼び出してもそれぞれの変数である
「protected ServletContext servletContext」
「protected HttpServletRequest request」
「protected HttpServletResponse response」
がnullのままです。
ですので、利用する前に各Locaterのgetを使って、値を取得してやります。
YyyControllerであれば、こんな感じです
package jp.tyato.test.controller.xxx; import org.slim3.controller.Controller; import org.slim3.controller.Navigation; import org.slim3.util.RequestLocator; import org.slim3.util.ResponseLocator; import org.slim3.util.ServletContextLocator; public class YyyController extends Controller { @Override public Navigation run() throws Exception { this.CheckParentMember(); //以降、実処理 } protected void CheckParentMember() { if( request == null ) { request = RequestLocator.get(); } if( response == null ) { response = ResponseLocator.get(); } if( servletContext == null ) { servletContext = ServletContextLocator.get(); } } }「ForDefaultController」「ZzzController」についても同様に定義してやります。
※まぁ実際に使うときに〜Locator.get()を呼び出してやればいいんですが。
こうすることで、
- Indexに一旦集約
- その都度の値により狙った処理を行うように制御
0 件のコメント:
コメントを投稿