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>
最新版本可在 Maven 中央仓库 查询
测试时需额外添加:
<dependency>
<groupId>org.javalite</groupId>
<artifactId>activeweb-testing</artifactId>
<version>1.15</version>
<scope>test</scope>
</dependency>
测试依赖最新版本在此
4. 应用结构
必须遵循特定的目录结构,典型 MVC 应用结构如下:
关键目录说明:
- ✅
app
包下需包含:controllers
、service
、config
、models
子包 - ✅ 视图文件位于
WEB-INF/views
,按控制器名划分子目录(如ArticleController
对应article/
目录) - ✅
web.xml
需配置<filter>
而非<servlet>
示例 web.xml
配置:
<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. 控制器(Controllers)
控制器是 ActiveWeb 的核心组件,必须位于 app.controllers
包:
public class ArticleController extends AppController {
// ...
}
5.1. 控制器 URL 映射
URL 自动按约定生成:
ArticleController
→http://host:port/contextroot/article
- 默认执行
index()
方法:
public void index() {
render("articles");
}
- 其他方法通过 URL 后缀访问:
访问:public void search() { render("search"); }
http://host:port/contextroot/article/search
⚠️ 可通过
@POST/@PUT/@DELETE/@GET
注解指定 HTTP 方法,未注解默认为 GET
5.2. 控制器 URL 解析规则
URL 生成规则:
- 单词控制器:
app.controllers.ArticleController
→/article
- 子包控制器:
app.controllers.baeldung.ArticleController
→/baeldung/article
- 多词控制器:
PublishedArticleController
→/published_article
(用下划线分隔)
5.3. 获取请求参数
通过 AppController
提供的方法获取参数:
// 获取单个参数
String keyword = param("key");
// 获取所有参数
Map<String, String[]> criterion = params();
简单粗暴,直接用就完事了
6. 视图(Views)
ActiveWeb 使用 Apache FreeMarker 模板引擎(非 JSP),视图文件需放在:
WEB-INF/views/{控制器名}/
目录下- 如
ArticleController
对应WEB-INF/views/article/
6.1. 控制器视图映射
默认规则:
index()
→/views/article/index.ftl
search()
→/views/article/search.ftl
手动指定视图:
// 同目录视图
render("articles");
// 跨目录视图
render("/common/error");
6.3. 带数据的视图
向视图传递数据:
// 方法一
view("articles", articleService.getArticles());
// 方法二(与 view() 等效)
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. 依赖管理
使用 Google Guice 管理 DI,以服务层为例:
定义服务接口:
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", "dev@baeldung.com"); // mock 邮箱
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. 测试
使用 JavaLite 的 JSpec 进行测试,测试类命名规则:{Controller}Spec
public class ArticleControllerSpec extends ControllerSpec {
// ...
}
基础测试示例:
@Test
public void whenReturnedArticlesThenCorrect() {
request().get("index");
a(responseContent())
.shouldContain("<td>Introduction to Mule</td>");
}
带参数测试:
@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 的核心概念和约定。该框架还有更多高级特性,建议参考官方文档深入学习。
本文示例代码可在 GitHub 获取。