結論としては、@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 件のコメント:
コメントを投稿