1. 概要

Javaエコシステムでは、 Spring Play Grailsなどの多くのWebフレームワークを利用できます。 ただし、それらのいずれも、完全に不変でオブジェクト指向であると主張することはできません。

このチュートリアルでは、Takesフレームワークについて説明し、ルーティング、要求/応答処理、単体テストなどの一般的な機能を使用して、単純なWebアプリケーションを作成します。

2. 取る

Takesは、nullメソッドもpublicstaticメソッドも使用しない不変のJava8Webフレームワークです。

また、フレームワークは、可変クラス、キャスト、またはリフレクションをサポートしていません。 したがって、これは真のオブジェクト指向フレームワークです。

テイクは、セットアップに構成ファイルを必要としません。 さらに、JSON/XML応答やテンプレートなどの組み込み機能を提供します。

3. 設定

まず、最新の takesMaven依存関係をpom.xmlに追加します。

<dependency>
    <groupId>org.takes</groupId>
    <artifactId>takes</artifactId>
    <version>1.19</version>
</dependency>

次に、Takeインターフェイスを実装するTakesHelloWorldクラスを作成しましょう。

public class TakesHelloWorld implements Take {
    @Override
    public Response act(Request req) {
        return new RsText("Hello, world!");
    }
}

Take インターフェースは、フレームワークの基本的な機能を提供します。 各Take要求ハンドラーとして機能し、actメソッドを介して応答を返します。

ここでは、 RsText クラスを使用して、 TakesHelloWorld テイクにリクエストが行われたときに、応答としてプレーンテキスト Hello、world!をレンダリングしました。

次に、 TakesApp クラスを作成して、Webアプリケーションを起動します。

public class TakesApp {
    public static void main(String... args) {
        new FtBasic(new TakesHelloWorld()).start(Exit.NEVER);
    }
}

ここでは、Frontインターフェースの基本的な実装を提供するFtBasicクラスを使用して、Webサーバーを起動し、リクエストをTakesHelloWorldテイクに転送しました。

Takesは、 ServerSocket クラスを使用して、独自のステートレスWebサーバーを実装します。 デフォルトでは、ポート80でサーバーを起動します。 ただし、コードでポートを定義できます。

new FtBasic(new TakesHelloWorld(), 6060).start(Exit.NEVER);

または、コマンドラインパラメータ–port を使用して、ポート番号を渡すことができます。

次に、Mavenコマンドを使用してクラスをコンパイルしましょう。

mvn clean package

これで、TakesAppクラスをIDEで単純なJavaアプリケーションとして実行する準備が整いました。

4. 走る

TakesAppクラスを別のWebサーバーアプリケーションとして実行することもできます。

4.1. Javaコマンドライン

まず、クラスをコンパイルしましょう。

javac -cp "takes.jar:." com.baeldung.takes.*

次に、Javaコマンドラインを使用してアプリケーションを実行できます。

java -cp "takes.jar:." com.baeldung.takes.TakesApp --port=6060

4.2. Maven

または、 exec-maven-pluginプラグインを使用して、Mavenを介して実行できます。

<profiles>
    <profile>
        <id>reload</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>3.0.0</version>
                    <executions>
                        <execution>
                            <id>start-server</id>
                            <phase>pre-integration-test</phase>
                            <goals>
                                <goal>java</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <mainClass>com.baeldung.takes.TakesApp</mainClass>
                        <cleanupDaemonThreads>false</cleanupDaemonThreads>
                        <arguments>
                            <argument>--port=${port}</argument>
                        </arguments>
                   </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

これで、Mavenコマンドを使用してアプリを実行できます。

mvn clean integration-test -Preload -Dport=6060

5. ルーティング

フレームワークは、 TkFork クラスを提供して、リクエストをさまざまなテイクにルーティングします。

たとえば、アプリケーションにいくつかのルートを追加しましょう。

public static void main(String... args) {
    new FtBasic(
        new TkFork(
            new FkRegex("/", new TakesHelloWorld()),
            new FkRegex("/contact", new TakesContact())
        ), 6060
    ).start(Exit.NEVER);
}

ここでは、FkRegexクラスを使用してリクエストパスを照合しました。

6. リクエスト処理

フレームワークは、HTTPリクエストを処理するためにorg.takes.rqパッケージにいくつかのデコレータクラスを提供します。

たとえば、 RqMethod インターフェイスを使用して、HTTPメソッドを抽出できます。

public class TakesHelloWorld implements Take { 
    @Override
    public Response act(Request req) throws IOException {
        String requestMethod = new RqMethod.Base(req).method(); 
        return new RsText("Hello, world!"); 
    }
}

同様に、 RqHeaders インターフェースを使用して、要求ヘッダーをフェッチできます。

Iterable<String> requestHeaders = new RqHeaders.Base(req).head();

RqPrint クラスを使用して、リクエストの本文を取得できます。

String body = new RqPrint(req).printBody();

同様に、 RqFormSmart クラスを使用して、フォームパラメーターにアクセスできます。

String username = new RqFormSmart(req).single("username");

7. 応答処理

Takesは、org.takes.rsパッケージでHTTP応答を処理するための多くの便利なデコレータも提供します。

応答デコレータは、Responseインターフェイスのheadおよびbodyメソッドを実装します。

たとえば、 RsWithStatus クラスは、ステータスコードを使用して応答をレンダリングします。

Response resp = new RsWithStatus(200);

応答の出力は、headメソッドを使用して確認できます。

assertEquals("[HTTP/1.1 200 OK], ", resp.head().toString());

同様に、 RsWithType クラスは、次のコンテンツタイプで応答をレンダリングします。

Response resp = new RsWithType(new RsEmpty(), "text/html");

ここで、RsEmptyクラスは空の応答をレンダリングします。

同様に、 RsWithBody クラスを使用して、ボディで応答をレンダリングできます。

それでは、 TakesContact クラスを作成し、説明したデコレータを使用して応答をレンダリングしましょう。

public class TakesContact implements Take {
    @Override
    public Response act(Request req) throws IOException {
        return new RsWithStatus(
          new RsWithType(
            new RsWithBody("Contact us at https://www.baeldung.com"), 
            "text/html"), 200);
    }
}

同様に、 RsJson クラスを使用して、JSON応答をレンダリングできます。

@Override 
public Response act(Request req) { 
    JsonStructure json = Json.createObjectBuilder() 
      .add("id", rs.getInt("id")) 
      .add("user", rs.getString("user")) 
      .build(); 
    return new RsJson(json); 
}

8. 例外処理

フレームワークには、例外的な条件を処理するためのフォールバックインターフェイスが含まれています。フォールバックシナリオを処理するためのいくつかの実装も提供します。

たとえば、 TkFallbackクラスを使用してHTTP404を処理し、ユーザーにメッセージを表示してみましょう。

public static void main(String... args) throws IOException, SQLException {
    new FtBasic(
        new TkFallback(
          new TkFork(
            new FkRegex("/", new TakesHelloWorld()),
            // ...
            ),
            new FbStatus(404, new RsText("Page Not Found"))), 6060
     ).start(Exit.NEVER);
}

ここでは、 FbStatus クラスを使用して、定義されたステータスコードのフォールバックを処理しました。

同様に、 FbChain クラスを使用して、フォールバックの組み合わせを定義できます。

new TkFallback(
    new TkFork(
      // ...
      ),
    new FbChain(
      new FbStatus(404, new RsText("Page Not Found")),
      new FbStatus(405, new RsText("Method Not Allowed"))
      )
    ), 6060
).start(Exit.NEVER);

また、 Fallback インターフェイスを実装して、例外を処理することもできます。

new FbChain(
    new FbStatus(404, new RsText("Page Not Found")),
    new FbStatus(405, new RsText("Method Not Allowed")),
    new Fallback() {
        @Override
        public Opt<Response> route(RqFallback req) {
          return new Opt.Single<Response>(new RsText(req.throwable().getMessage()));
        }
    }
)

9. テンプレート

Apache VelocityをTakesWebアプリと統合して、いくつかのテンプレート機能を提供しましょう。

まず、 speed-engine-coreMaven依存関係を追加します。

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.2</version>
</dependency>

次に、 RsVelocity クラスを使用して、actメソッドのテンプレート文字列とバインディングパラメーターを定義します。

public class TakesIndex implements Take {
    @Override
    public Response act(Request req) throws IOException {
        return new RsHtml(
            new RsVelocity("${username}", new RsVelocity.Pair("username", "Baeldung")));
        );
    }
}

ここでは、RsHtmlクラスを使用してHTML応答をレンダリングしました。

また、RsVelocityクラスでベロシティテンプレートを使用できます。

new RsVelocity(this.getClass().getResource("/templates/index.vm"), 
    new RsVelocity.Pair("username", username))
);

10. ユニットテスト

フレームワークは、偽のリクエストを作成する RqFake クラスを提供することにより、任意のTakeの単体テストをサポートします。

たとえば、 JUnit を使用して、TakesContactクラスの単体テストを作成しましょう。

String resp = new RsPrint(new TakesContact().act(new RqFake())).printBody();
assertEquals("Contact us at https://www.baeldung.com", resp);

11. 統合テスト

JUnitと任意のHTTPクライアントを使用してアプリケーション全体をテストできます。

フレームワークは、ランダムポートでサーバーを起動する FtRemote クラスを提供し、Takeの実行にリモートコントロールを提供します。

たとえば、統合テストを作成して、TakesContactクラスの応答を確認してみましょう。

new FtRemote(new TakesContact()).exec(
    new FtRemote.Script() {
        @Override
        public void exec(URI home) throws IOException {
            HttpClient client = HttpClientBuilder.create().build();    
            HttpResponse response = client.execute(new HttpGet(home));
            int statusCode = response.getStatusLine().getStatusCode();
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            
            assertEquals(200, statusCode);
            assertEquals("Contact us at https://www.baeldung.com", result);
        }
    });

ここでは、 Apache HttpClient を使用してサーバーにリクエストを送信し、応答を確認しました。

12. 結論

このチュートリアルでは、単純なWebアプリケーションを作成して、Takesフレームワークについて説明しました。

まず、Mavenプロジェクトでフレームワークをセットアップし、アプリケーションを実行する簡単な方法を見てきました。

次に、ルーティング、要求/応答処理、単体テストなどのいくつかの一般的な機能を調べました。

最後に、フレームワークによって提供されるユニットテストと統合テストのサポートについて検討しました。

いつものように、すべてのコード実装はGitHub利用できます。