Home > Java > SAStrutsのURL設計で課題

SAStrutsのURL設計で課題

  • 2008-08-12 (火) 12:56
  • Java

SAStrutsにおけるURLは、Actionのパッケージとクラス名によって基本的に決まる。
綺麗なURL(パラメータをURLのpathに含めたり・・・など)を作りたいときはurlPatternを利用することになる。

で、今回悩んでいるのはこんなこと。
お尻にくっつくパラメーターではなく、大分類みたいなものでURLを分けたいときはどうすればよいか?
大分類を、URLの頭のほうに持っていけるのか?

例えばショッピングサイトを作るとする。
そのサイトでは、本と文房具を売っているとする。

例えばこんな感じのURLにしたいとする。

  • / -> サイトのトップページ
  • /book/ -> 本カテゴリーのトップ
  • /book/feature/ -> 特集ページ
  • /book/search/ -> 検索
  • /book/search/result/ -> 検索結果
  • /book/item/{id}/ -> 商品ページ
  • /stationery/ -> 文具カテゴリーのトップ
  • /stationery/feature/ -> 特集ページ
  • /stationery/search/ -> 検索
  • /stationery/search/result/ -> 検索結果
  • /stationery/item/{id}/ -> 商品ページ
  • /cart/ -> カートの中身

Actionは、FeatureActionとかSearchActionとか作るんだろうけど、URLの第一階層のカテゴリーをうまく扱えない。

「/feature/book/」「/search/book/」でいいじゃないかとも思うけど、パンくずとURLがずれるよね。
気にするなという人もいるだろうけどさ。

もしこのURLを実現するとなるとぱっと思いつく案は4つ。
(そもそもできるのかとか、どうやってやるとかは考えずぱっと思いついた案を出しただけ)

  1. コンテキストごと分けてしまう
  2. mod_rewrite、もしくはそれに準じるようなものでごにょごにょがんばる
  3. RoutingFilterかRequestProcessorあたりを拡張してがんばる
  4. フォワード専用のActionを作ってがんばる

1番目はいくらなんでもメモリの無駄遣い過ぎるし、カテゴリに変更が入るたびにインフラに近い部分で設定が変わるのはいけてない。
2番目はメンテできなくなりそうだし、3番目はSAStruts本体の動きを変更することになるから微妙・・・。
4番目は、これはこれでメンテできなったり、カオスになりそう。

素直にあきらめたほうがいいのかも?

こうやって考えると、DjangoのURLの仕組みは単純で秀逸だなーと思う。

Comments:6

ひが 08-08-13 (水) 17:12

第一階層もBookActionを作っておけば、特に問題ないと思いますが。
どの辺をできないと思っていますか。

nmasatomo 08-08-14 (木) 13:15

言葉足らずでした。

/book/search/
/stationery/search/

上記のURLは、両方とも同じアクション・メソッドが動き、bookとstationeryのどちらで呼ばれたのかアクション内部から判断できるようにしたいというのがやりたいことです。

綺麗ではない(?)URLでいうと、「/search?category=book」「/search?category=stationery」みたいな感じでしょうか。
/search/book/と/search/stationery/とすると実装上は自然なんですが、サイト構造とURLは一致しなくなってしまいます。
今回の要件では、bookとstationeryは同じ実装だけど別サイトっぽい扱いにしたいので・・・

共通処理をServiceに切り出してbook.SearchActionとstationery.SearchActionから呼び出すとか、親Actionを作っておいて各階層のActionはそれらを継承するだけ、なんていう案もあるかとは思いますが、できればそれすらやりたくないなぁと。
カテゴリーを後から簡単に、動的に追加したいからです。(ユースケースもsearchだけじゃなく実際にはたくさん存在することになります)

というわけで、どこかの処理でURLの第一階層をリクエストスコープなどに保存して、共通のSearchActionにフォワードするという処理をやればなんとかなるかなーと思っているところです。
相当無理やりな感じになってしまいますが・・・。

ひが 08-08-14 (木) 17:34

IndexActionで

@Execute(urlPattern = “{category}/search”, …)
public String search() {

}

みたいにやれば大丈夫。

nmasatomo 08-08-14 (木) 22:28

たびたびありがとうございます。

確かに。
ユースケースや画面数が少ないのであればそれでいいですね。例で出したsearchだけであればそのやり方でうまくいきそうです。

ただ、categoryの下にユースケースがいくつもあったり、画面数が数十以上あったりすると、さすがにIndexActionが肥大化しすぎるし、分業が難しくなりそうです。(今回はまさにそんな感じになりそうです。)

頂いたヒントも含めて(要件も含め)どうするのがいいのかもう少し考えてみます。

# category毎に別サイトっぽくするなら、コンテキストを分ければ本当は一番しっくりくるのに。
# リリース作業やインフラ影響を考えるとその案はとりずらいんですよね。
# こう思うと擬似的なコンテキストをつくりたい、というSAStrutsとは少し別の話なのかも?

FUYO 09-06-03 (水) 17:24

↑同じような状況に遭遇しています。nmasatomoさんはどのようにして回避されましたか?

nmasatomo 09-06-03 (水) 17:53

ひがさんは、MLでも似たような話しに対して、IndexActionでプロキシする方法を提示してくれていますね。
https://ml.seasar.org/archives/seasar-user/2008-October/016131.html

私の場合は、RoutingFilterを改造して対応しました。
以下がそのときのエントリーです。
http://blog.joyfullife.jp/archives/2008/09/05220502.php

簡単に言うと、Actionは疑似コンテキスト(のようなもの?)なしでアクセスできる場所において、RoutingFilterでURLを書き換えてフォワードするといった対応です。。
# 疑似コンテキストをURIから抜いたときには、アクセス制御をいれるなど細かい対応もしました。

この方法の問題点は、aタグやformタグ、もしくは画像のパスまで、パスの一番上の疑似コンテキスト(のようなもの?)を意識してくっつけてあげる必要があることです。
本物のコンテキストを自動的に保管してくれるかのように。

さらに、疑似コンテキストはあくまでも疑似コンテキストなので、疑似コンテキストなしでアクセスするページがあったりすると、その辺も対応しなきゃならないので思ったよりも複雑になりました。
改造RoutingFilterをいろいろな設定で動作を制御できるようにしたり、タグリブやEL関数で簡単に疑似コンテキストを保管できるようにしたりといった対応を行いました.
sastrutsの上にさらにURLに関するフレームワークを乗せるような感じです。

開発者がそれなりの人数で、フレームワークに手を入れるといった対応を厭わないのであれば、こんな対応もありかなーと思います。
# 私が関わったプロジェクトではこの仕組みでうまく動いていました。

フレームワークを自作/改造することに抵抗があったり、少人数もしくは画面数が少ないプロジェクトであれば、ひがさんの提示している方法のほうがよいと思います。

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://blog.joyfullife.jp/archives/2008/08/12125650.php/trackback
Listed below are links to weblogs that reference
SAStrutsのURL設計で課題 from 30からのBlog

Home > Java > SAStrutsのURL設計で課題

Search
Feeds
Meta

Return to page top