snbhsmt_log

ネットワークとコンピュータ、その他いろいろ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Slim3 のルータを拡張するサンプル

Slim3 の AppRouter 周りは色々拡張できるなあとソースを読んでいて思ったので、 正規表現でルーティング指定できるものをちょっと書いてみました。

パスの変換自体は java.util.regex パッケージをそのまま使っているだけです。

AppRouter implements Router して、まったく独自のルーティングルールに する事もできるけど、RouterImpl#addRouting() もそのまま利用できる様に Routing の方を拡張する方法にしました。

オマケにすらならない様なテスト付き。

package com.example.regexrouter.controller;

import javax.servlet.http.HttpServletRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class RegexRouterTest {

    RegexRouter router = new RegexRouter();
    HttpServletRequest request = mock(HttpServletRequest.class);

    @Test
    public void defaultRoute() throws Exception {
        router.addRouting("/path/{to}/{file}", "/aaa?bbb={file}&ccc={to}");
        assertThat(router.route(request, "/path/foo/bar"),
                is("/aaa?bbb=bar&ccc=foo"));
    }

    @Test
    public void regexRoute() throws Exception {
        router.addRegexRouting("^(.+)$", "/?act=$1");
        assertThat(router.route(request, "/foo/bar"), is("/?act=/foo/bar"));
    }

    @Test
    public void isStatic() throws Exception {
        assertThat(router.isStatic("/index.html"), is(true));
        assertThat(router.isStatic("/foo"), is(false));
    }

    @Before
    public void setUp() {
        when(request.getCharacterEncoding()).thenReturn("UTF-8");
    }

    @After
    public void tearDown() {
        reset(request);
    }
}

以下が書いたものです。

package com.example.regexrouter.controller;

import org.slim3.controller.router.RouterImpl;

public class RegexRouter extends RouterImpl {

    public void addRegexRouting(String from, String to) throws NullPointerException {
        routingList.add(new RegexRouting(from, to));
    }
}
package com.example.regexrouter.controller;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.slim3.controller.router.Routing;

public class RegexRouting extends Routing {

    public RegexRouting(String from, String to) throws NullPointerException {
        super(from, to);
    }

    @Override
    protected void setFrom(String from) throws NullPointerException {
        if (from == null) {
            throw new NullPointerException("The from parameter is null.");
        }
        this.from = from;
        fromPattern = Pattern.compile(from);
    }

    @Override
    protected void setTo(String to) {
        if (to == null) {
            throw new NullPointerException("The to parameter is null.");
        }
        this.to = to;
    }

    @Override
    public String route(HttpServletRequest request, String path)
            throws NullPointerException {
        if (request == null) {
            throw new NullPointerException("The request parameter is null.");
        }
        if (path == null) {
            throw new NullPointerException("The path parameter is null.");
        }
        Matcher matcher = fromPattern.matcher(path);
        if (!matcher.find()) {
            return null;
        }
        return matcher.replaceFirst(to);
    }
}

実際には、こんな感じで使用する。
(2) の指定だけすると、/_ah/* や isStatic() が true の場合でも IndexController にしか処理がまわってこなくなるので注意しなくちゃならない。

package com.example.regexrouter.controller;

public class AppRouter extends RegexRouter {

    public AppRouter() {
        addRegexRouting("^/hoge/(.*)$", "/?hoge=/$1");
        addRouting("/foo/{bar}", "/foo?param={bar}");
        // addRegexRouting("^(.+)$", "/?path=$1");        // (2)
    }
}
スポンサーサイト

« slim3 のリクエスト処理の流れ|Top|AppRouter のテストはどう書く »

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://snbhsmt.blog110.fc2.com/tb.php/125-79258378

Top

HOME

snbhsmt

Author:snbhsmt
Google Profiles

http://www.ksky.ne.jp/~snbhsmt/

全ての記事を表示する

この人とブロともになる

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。