ActiveWeb 簡介

Java,REST
Remote
1
11:44 AM · Dec 01 ,2025

1. 概述

在本文中,我們將介紹 Activeweb – JavaLite 提供的全棧 Web 框架,它提供了開發動態 Web 應用程序或 RESTful Web 服務所需的一切。

2. 基本概念和原則

Activeweb 採用“約定優於配置” – 這意味着它可配置,但具有合理的默認值,並且不需要額外的配置。我們只需要遵循幾個預定義的約定,例如命名類、方法和字段的特定格式。

它還通過重新編譯和加載源代碼到正在運行的容器(默認情況下為 Jetty)簡化了開發。

對於依賴管理,它使用 Google Guice 作為 DI 框架;要了解更多關於 Guice 的信息,請查看我們的指南這裏

3. Maven 設置為了開始,我們首先添加必要的依賴項:

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

最新版本可以在這裏找到:這裏

此外,為了測試應用程序,我們需要 activeweb-testing 依賴項:

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

查看最新版本 這裏

4. 應用結構

正如我們討論的,應用程序的結構需要遵循一定的約定;以下是典型 MVC 應用程序的結構:

active web

如我們所見,控制器服務配置模型應該位於app包中的各自子包中。

視圖應該位於WEB-INF/views目錄中,每個視圖擁有自己的子目錄,基於控制器名稱。例如,app.controllers.ArticleController應該有一個article/子目錄,其中包含所有針對該控制器的視圖文件。

部署描述符或web.xml通常包含一個<filter>和一個對應的<filter-mapping>。由於框架是一個 Servlet 過濾器,而不是<servlet>配置,因此有過濾器配置:

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

我們還需要一個<init-param>root_controller,用於定義應用程序的默認控制器——類似於home控制器:

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

5. Controllers

Controllers是ActiveWeb應用程序的主要組件;並且,正如前面提到的,所有Controllers都應該位於app.controllers包內:

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

請注意,Controller繼承了org.javalite.activeweb.AppController

5.1. Controller URL Mapping

Controllers會根據約定自動映射到URL。例如,ArticleController會被映射到:

http://host:port/contextroot/article

現在,這將映射到Controller中的默認動作。動作只是Controller中的方法。將默認方法命名為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方法具有Controller動作。只需使用@POST, @PUT, @DELETE, @GET, @HEAD註解方法。

5.2. Controller URL Resolution

框架使用Controller名稱和子包名稱來生成Controller URL。例如,app.controllers.ArticleController.java,URL:

http://host:port/contextroot/article

如果Controller位於子包中,URL將簡化為:

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

對於具有多個單詞的Controller名稱(例如,app.controllers.PublishedArticleController.java),URL將使用下劃線分隔:

http://host:port/contextroot/published_article

5.3. Retrieving Request Parameters

在Controller中,我們可以使用param()params()方法從AppController類中檢索請求參數。第一個方法接受字符串參數,即要檢索的參數名稱:

public void search() {

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

}

我們可以使用後者來獲取所有參數,如果需要:

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

6. Views

在 ActiveWeb 術語中,視圖通常被稱為模板;這主要是因為它使用了 Apache FreeMarker 模板引擎而不是 JSPs。 您可以在我們的指南中瞭解更多關於 FreeMarker 的信息,這裏。

將模板放在 WEB-INF/views 目錄中。 每個控制器都應該有一個子目錄,名稱與該控制器相對應,幷包含該控制器所需的所有模板。

6.1. Controller View Mapping

當控制器被訪問時,默認動作 index() 會被執行,並且框架會從 WEB-INF/views/article/ 目錄中選擇 index.ftl 模板用於該控制器。 同樣,對於任何其他動作,視圖將根據動作名稱進行選擇。

這並不總是我們想要的結果。 有時我們可能想要根據內部業務邏輯返回一些視圖。 在這種情況下,render() 方法來控制該過程。 從父類 org.javalite.activeweb.AppController 中:

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

請注意,自定義視圖的位置也應在與該控制器同一視圖目錄中。 如果不是這樣,請在將模板名稱與模板所在的目錄名稱前綴並將其傳遞給 render() 方法:

render("/common/error");

6.3. Views With Data

要將數據發送到視圖中,org.javalite.activeweb.AppController 提供了 view() 方法:

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

它接受兩個參數。 第一個參數是用於在模板中訪問對象的對象名稱,第二個參數是包含數據的對象。

我們還可以使用 assign() 方法將數據傳遞到視圖中。 view() 方法和 assign() 方法之間沒有區別,我們可以選擇任何一種:

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 應用程序的單元測試,使用 JSpec 庫(來自 JavaLite)進行編寫。

我們將使用 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. 部署應用程序

可以將應用程序部署到任何servlet容器,例如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>
...

最新版本的插件可以在這裏找到:這裏

現在,我們可以啓動它:

mvn jetty:run

10. 結論

在本文中,我們學習了 ActiveWeb 框架的基本概念和約定。除此之外,該框架還具有我們討論過的更多功能和能力。

請參閲官方 文檔 以獲取更多詳細信息。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.