Slim3 のスタートガイドを確認してみた

以下から始まるソレの「ブランクプロジェクトの作成」あたりから。

で、完成版を以下に投入させて頂いております。

とりあえず気づきを以下に列挙してみます。

ソース掘削

終わりまで済ませて再度ソースを確認してみるに

war/WEB-INF/web.xml の修正

以下のみ。

    <context-param>
        <param-name>slim3.rootPackage</param-name>
        <param-value>jp.shuri.slim3.firsttutorial</param-value>
    </context-param>

ソースパケジ的にはこの rootPackage の下に

  • controller
  • meta
  • model
  • service

という MVC な機能毎のパケジがある形。

IndexController.java

パケジ名の定義が以下。

package jp.shuri.slim3.firsttutorial.controller.twitter;

これ、/twitter/ というパスに該当するクラスになる模様。一つのクラスが一つの URL に、という形になってるみたいですが、メソドで云々というのにどのように対応しているのかは現時点では不明です。
基本的には dispatcher なクラスから run というメソドが呼び出されるようでこのクラスの定義は以下な形になってます。

public class IndexController extends Controller {
    
    private TwitterService service = new TwitterService();

    @Override
    public Navigation run() throws Exception {
        List<Tweet> tweetList = service.getTweetList();
        requestScope("tweetList", tweetList);
        return forward("index.jsp");
    }
}

ちなみに index.jsp では以下な形で変数なオブジェクトを扱っています。

<c:forEach var="e" items="${tweetList}">
${f:h(e.content)}
<hr />
</c:forEach>

requestScope というメソドでマッピングしているのだろうと類推。また、TwitterService というクラスですが該当部分が以下な定義ですね。

    private TweetMeta t = new TweetMeta();
    
// 中略
    
    public List<Tweet> getTweetList() {
        return Datastore.query(t).sort(t.createdDate.desc).asList();
    }

基本的にビジネスロジックな操作はこちらで、という流儀な模様。しかし上の書き方で全件取得して云々、というのはまだ慣れないカンジがします。
とりあえず Datastore.query というメソドは別途確認必要ということで。

tweet というアクション

index.jsp には以下な記述もあります。フォームですね。

<form method="post" action="tweet">
<textarea name="content"></textarea><br />
<input type="submit" value="tweet"/>
</form>

こちらは TweetController.java がよしなに処理をする模様。パケジは以下な宣言。

package jp.shuri.slim3.firsttutorial.controller.twitter;

パスとしては /twitter/ なのですがこのコントローラクラスの名前から /twitter/tweet なるパスの要求を取り扱う形になる模様。正に上で引用したフォームからのアクションを、という形になりますね。
定義は以下。

    private TwitterService service = new TwitterService();

    @Override
    public Navigation run() throws Exception {
        service.tweet(new RequestMap(request));
        return redirect(basePath);
    }

TwitterService#tweet を呼び出して index.jsp (basePath) にリダイレクトしてます。
まず tweet な手続きから確認を。

    public Tweet tweet(Map<String, Object> input) {
        Tweet tweet = new Tweet();
        BeanUtil.copy(input, tweet);
        Transaction tx = Datastore.beginTransaction();
        Datastore.put(tweet);
        tx.commit();
        return tweet;
    }

こちらも非常に興味深くて BeanUtil.copy でリクエストの属性値 (ここでは "content") を Tweet なモデルの属性に copy する、ということをやってるみたいです。ここでも名前ベースの処理になっているのですね。
モデルクラスとして定義されている Tweet.java には以下な属性の記述を追加しています。手を入れたのは確かここだけのはず。

    private String content;
    
    private Date createdDate = new Date();

属性としては private なんですが、ミドルウェア側でよしなに処理をしてくれているのでしょうね。ここまで盛り込んでみて確かにシンプルなのですが、もう少し色々やってみる必要はあるかも。