ActiveWebの紹介

1概要

この記事では、http://javalite.io/activeweb[Activeweb] - JavaLiteのフルスタックWebフレームワーク - について説明します。動的WebアプリケーションまたはREST対応Webサービスの開発に必要なすべてを提供します。

2基本的な考え方と原則

Activewebは「設定上の規則」を利用します。つまり、設定可能ですが、適切なデフォルト設定があり、追加の設定は不要です。クラス、メソッド、および特定の定義済みフォーマットでのフィールドの命名など、いくつかの定義済み規則に従う必要があります。

また、ソースを実行中のコンテナ(デフォルトではJetty)に再コンパイルおよび再ロードすることで開発を簡素化します。

依存関係管理のために、DIフレームワークとしてGoogle Guiceを使います。 Guiceについてさらに学ぶために、私たちのリンクを見てください:

3. Mavenのセットアップ

まずはじめに、必要な依存関係を追加しましょう。

<dependency>
    <groupId>org.javalite</groupId>
    <artifactId>activeweb</artifactId>
    <version>1.15</version>
</dependency>

最新版はhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.javalite%22%20AND%20a%3A%22activeweb%22[here]にあります。

さらに、アプリケーションをテストするには、 activeweb-testing 依存関係が必要です。

<dependency>
    <groupId>org.javalite</groupId>
    <artifactId>activeweb-testing</artifactId>
    <version>1.15</version>
    <scope>test</scope>
</dependency>

最新バージョンhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.javalite%22%20AND%20a%3A%22activeweb-testing%22[ここ]をチェックしてください。

4アプリケーション構造

すでに説明したように、アプリケーション構造は特定の規則に従う必要があります。これは典型的なMVCアプリケーションのように見えるものです:

画像

ご覧のとおり、 controllers service config 、および models は、 app パッケージ内の独自のサブパッケージに配置する必要があります。

ビューは WEB-INF/views ディレクトリに配置する必要があります。各ビューはコントローラ名に基づいた独自のサブディレクトリです。たとえば、 app.controllers.ArticleController には、そのコントローラのすべてのビューファイルを含む article/ サブディレクトリが必要です。

デプロイメント記述子または web.xml には通常 <filter> とそれに対応する <filter-mapping>を含める必要があります。フレームワークはサーブレットフィルタであるため、 <servlet> __設定の代わりにフィルタ設定があります。 :

...
<filter>
    <filter-name>dispatcher</filter-name>
    <filter-class>org.javalite.activeweb.RequestDispatcher</filter-class>
...
</filter>
...

アプリケーションのデフォルトコントローラを定義するには、 <初期パラメータ> ルートコントローラ も必要です。

...
<init-param>
    <param-name>root__controller</param-name>
    <param-value>home</param-value>
</init-param>
...

5コントローラー

コントローラは、ActiveWebアプリケーションの主要コンポーネントです。また、前述のように、すべてのコントローラーは app.controllers パッケージ内に配置する必要があります。

public class ArticleController extends AppController {
   //...
}

コントローラが org.javalite.activeweb.AppController. を拡張していることに注意してください。

5.1. コントローラのURLマッピング

コントローラは、規約に基づいて自動的にURLにマッピングされます。たとえば、 ArticleController は次のようにマッピングされます。

http://host:port/contextroot/article

これで、これはコントローラ内のデフォルトのデフォルトアクションにマッピングされます。アクションはコントローラ内部のメソッドに他なりません。デフォルトのメソッドに__index()という名前を付けます。

public class ArticleController extends AppController {
   //...
    public void index() {
        render("articles");
    }
   //...
}

他のメソッドまたはアクションの場合は、URLにメソッド名を追加します。

public class ArticleController extends AppController {
   //...

    public void search() {
        render("search");
    }
}

URL

http://host:port/contextroot/article/search

HTTPメソッドに基づいてコントローラのアクションを実行することもできます。 __ @ POST、@ PUT、@ DELETE、@ GET、@ HEADのいずれかでメソッドに注釈を付けるだけです。アクションに注釈を付けない場合、デフォルトでGETと見なされます。

5.2. コントローラのURL解決

フレームワークはコントローラ名とサブパッケージ名を使用してコントローラURLを生成します。たとえば、 app.controllers.ArticleController.java URLです。

http://host:port/contextroot/article

コントローラがサブパッケージ内にある場合、URLは単に次のようになります。

http://host:port/contextroot/baeldung/article

複数の単語を含むコントローラ名( app.controllers.PublishedArticleController.java など)の場合、URLはアンダースコアを使用して区切られます。

http://host:port/contextroot/published__article

5.3. リクエストパラメータの取得

コントローラの内部では、 AppControllerクラスの param() メソッドまたは params()__メソッドを使用してリクエストパラメータにアクセスします。

public void search() {

    String keyword = param("key");
    view("search",articleService.search(keyword));

}

また、必要に応じて、後者を使用してすべてのパラメータを取得できます。

public void search() {

    Map<String, String[]> criterion = params();
   //...
}

6. 閲覧数

ActiveWeb用語では、ビューはしばしばテンプレートと呼ばれます。これは主に、JSPではなくApache FreeMarker テンプレートエンジンを使用しているためです。 FreeMarkerのリンクについてもっと読むことができます:/freemarker-in-spring-mvc-tutorial[私たちのガイドでは、ここ]

テンプレートを WEB-INF/views ディレクトリに配置します。すべてのコントローラには、その名前が必要とするすべてのテンプレートを保持するサブディレクトリが必要です。

6.1. コントローラビューマッピング

コントローラがヒットすると、デフォルトのアクション index()が実行され、フレームワークはそのコントローラのfromディレクトリから WEB-INF/views/article/index.ftl__テンプレートを選択します。同様に、他のアクションについても、ビューはアクション名に基づいて選択されます。

これは必ずしも私たちが望むことではありません。時には私たちは内部のビジネスロジックに基づいていくつかのビューを返したいと思うかもしれません。このシナリオでは、** 親 org.javalite.activeweb.AppController クラスの__render()メソッドを使用してプロセスを制御できます。

public void index() {
    render("articles");
}

カスタムビューの場所も、そのコントローラの同じビューディレクトリにある必要があります。そうでない場合は、テンプレート名の前にテンプレートがあるディレクトリ名をプレフィックスとして付けて、 render() メソッドに渡します。

render("/common/error");

6.3. データ付きビュー

データをビューに送信するために、 org.javalite.activeweb.AppController view() メソッドを提供します。

view("articles", articleService.getArticles());

これには2つのパラメータが必要です。まず、テンプレート内のオブジェクトにアクセスするために使用されるオブジェクト名、次にデータを含むオブジェクトです。

assign() メソッドを使ってデータをビューに渡すこともできます。 view()と assign() メソッドの間に全く違いはありません - 私たちはそれらのうちの1つを選ぶことができます:

assign("article", articleService.search(keyword));

テンプレート内のデータをマッピングしましょう。

<@content for="title">Articles</@content>
...
<#list articles as article>
    <tr>
        <td>${article.title}</td>
        <td>${article.author}</td>
        <td>${article.words}</td>
        <td>${article.date}</td>
    </tr>
</#list>
</table>

7. 依存関係を管理する

オブジェクトとインスタンスを管理するために、ActiveWebは依存関係管理フレームワークとしてGoogle Guiceを使用します。

アプリケーションにサービスクラスが必要だとしましょう。これにより、ビジネスロジックとコントローラが分離されます。

まずサービスインターフェースを作成しましょう。

public interface ArticleService {

    List<Article> getArticles();
    Article search(String keyword);

}

そして実装:

public class ArticleServiceImpl implements ArticleService {

    public List<Article> getArticles() {
        return fetchArticles();
    }

    public Article search(String keyword) {
        Article ar = new Article();
        ar.set("title", "Article with "+keyword);
        ar.set("author", "baeldung");
        ar.set("words", "1250");
        ar.setDate("date", Instant.now());
        return ar;
    }
}

それでは、このサービスをGuiceモジュールとしてバインドしましょう。

public class ArticleServiceModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(ArticleService.class).to(ArticleServiceImpl.class)
          .asEagerSingleton();
    }
}

最後に、これをアプリケーションコンテキストに登録し、必要に応じてコントローラに注入します。

public class AppBootstrap extends Bootstrap {

    public void init(AppContext context) {
    }

    public Injector getInjector() {
        return Guice.createInjector(new ArticleServiceModule());
    }
}

この設定クラス名は AppBootstrap でなければならず、 app.config パッケージ内になければなりません。

最後に、コントローラにそれを注入する方法は次のとおりです。

@Inject
private ArticleService articleService;

8テスト中

ActiveWebアプリケーションのユニットテストは、JavaLiteのhttp://javalite.io/jspec[JSpec]ライブラリを使用して書かれています。

JSpecの org.javalite.activeweb.ControllerSpec クラスを使用してコントローラーをテストし、テストクラスにも同様の規則に従って名前を付けます。

public class ArticleControllerSpec extends ControllerSpec {
   //...
}

名前はテストしているコントローラと同じで、末尾に「Spec」が付いていることに注意してください。

これがテストケースです。

@Test
public void whenReturnedArticlesThenCorrect() {
    request().get("index");
    a(responseContent())
      .shouldContain("<td>Introduction to Mule</td>");
}

request() メソッドはコントローラへの呼び出しをシミュレートし、対応するHTTPメソッド get()、 はアクション名を引数として取ります。

params() メソッドを使用してパラメータをコントローラに渡すこともできます。

@Test
public void givenKeywordWhenFoundArticleThenCorrect() {
    request().param("key", "Java").get("search");
    a(responseContent())
      .shouldContain("<td>Article with Java</td>");
}

複数のパラメータを渡すために、この流暢なAPIを使ってメソッドを連鎖することもできます。

9.アプリケーションのデプロイ

Tomcat、WildFly、Jettyなどのサーブレットコンテナにアプリケーションをデプロイすることは可能です。もちろん、デプロイとテストを行う最も簡単な方法は、Maven Jettyプラグインを使用することです。

...
<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.4.8.v20171121</version>
    <configuration>
        <reload>manual</reload>
        <scanIntervalSeconds>10000</scanIntervalSeconds>
    </configuration>
</plugin>
...

プラグインの最新バージョンはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.eclipse.jetty%22%20AND%20a%3A%22jetty-maven-plugin%です。 22[ここ]

これで、ようやく起動できます。

mvn jetty:run

10結論

この記事では、ActiveWebフレームワークの基本概念と規則について学びました。これらに加えて、フレームワークには、ここで説明したものよりも多くの機能があります。

詳細については、公式のhttp://javalite.io/documentation#activeweb[documentation]を参照してください。

そして、いつものように、この記事で使われているサンプルコードはhttps://github.com/eugenp/tutorials/tree/master/java-lite[GitHubで利用可能]です。