Introduction to ActiveWeb
1.概述
在本文中,我们将说明Activeweb(来自JavaLite的完整堆栈Web框架),它提供了开发动态Web应用程序或REST-ful Web服务所需的一切。
2.基本概念和原则
Activeweb利用"约定之上的配置" –这意味着它是可配置的,但是具有合理的默认值,并且不需要其他配置。 我们只需要遵循一些预定义的约定,例如以某种预定义的格式命名类,方法和字段。
通过重新编译源代码并将其重新加载到正在运行的容器(默认情况下为Jetty)中,它还简化了开发。
对于依赖关系管理,它使用Google Guice作为DI框架; 要了解有关Guice的更多信息,请在此处查看我们的指南。
3. Maven安装
首先,让我们先添加必要的依赖项:
1 2 3 4 5 | <dependency> <groupId>org.javalite</groupId> <artifactId>activeweb</artifactId> <version>1.15</version> </dependency> |
最新版本可以在这里找到。
此外,为了测试应用程序,我们需要activeweb-testing依赖项:
1 2 3 4 5 6 | <dependency> <groupId>org.javalite</groupId> <artifactId>activeweb-testing</artifactId> <version>1.15</version> <scope>test</scope> </dependency> |
在此处查看最新版本。
4.应用结构
正如我们所讨论的,应用程序结构需要遵循一定的约定。 这是典型的MVC应用程序的外观:
如我们所见,控制器,服务,配置和模型应位于应用程序包中各自的子包中。
如我们所见,控制器,服务,配置和模型应位于应用程序包中各自的子包中。
视图应该位于WEB-INF / views目录中,每个视图都有基于控制器名称的自己的子目录。 例如app.controllers.ArticleController应该有一个article /子目录,其中包含该控制器的所有视图文件。
部署描述符或web.xml通常应包含
1 2 3 4 5 6 7 | ... <filter> <filter-name>dispatcher</filter-name> <filter-class>org.javalite.activeweb.RequestDispatcher</filter-class> ... </filter> ... |
我们还需要一个
1 2 3 4 5 6 | ... <init-param> <param-name>root_controller</param-name> <param-value>home</param-value> </init-param> ... |
5.控制器
控制器是ActiveWeb应用程序的主要组件。 并且,如前所述,所有控制器都应位于app.controllers包内:
1 2 3 | public class ArticleController extends AppController { // ... } |
注意,该控制器正在扩展org.javalite.activeweb.AppController。
5.1。 控制器URL映射
控制器会根据约定自动映射到URL。 例如,ArticleController将映射到:
1 | http://host:port/contextroot/article |
现在,这会将它们映射到控制器中的默认默认操作。 动作不过是控制器内部的方法。 将默认方法命名为index():
1 2 3 4 5 6 7 | public class ArticleController extends AppController { // ... public void index() { render("articles"); } // ... } |
对于其他方法或操作,将方法名称附加到URL:
1 2 3 4 5 6 7 | public class ArticleController extends AppController { // ... public void search() { render("search"); } } |
网址:
1 | http://host:port/contextroot/article/search |
我们甚至可以基于HTTP方法进行控制器操作。 只需使用@ POST,@ PUT,@ DELETE,@ GET和@HEAD中的任何一个注释该方法。 如果我们不注释操作,则默认情况下将其视为GET。
5.2。 控制器URL解析
框架使用控制器名称和子包名称来生成控制器URL。 例如app.controllers.ArticleController.java URL:
1 | http://host:port/contextroot/article |
如果控制器在子包中,则URL会变成:
1 | http://host:port/contextroot/baeldung/article |
对于具有多个单词的控制器名称(例如app.controllers.PublishedArticleController.java),URL将使用下划线分隔:
1 | http://host:port/contextroot/published_article |
5.3。 检索请求参数
在控制器内部,我们可以使用AppController类中的param()或params()方法访问请求参数。 第一个方法采用String参数–要检索的参数名称:
1 2 3 4 5 6 | public void search() { String keyword = param("key"); view("search",articleService.search(keyword)); } |
如果需要,我们可以使用后面的方法获取所有参数:
6.意见
<
在ActiveWeb术语中,视图通常称为模板。 这主要是因为它使用Apache FreeMarker模板引擎而不是JSP。 您可以在此处的指南中阅读有关FreeMarker的更多信息。
将模板放在WEB-INF / views目录中。 每个控制器应按其名称包含一个子目录,该子目录包含其所需的所有模板。
6.1。 控制器视图映射
当按下控制器时,将执行默认操作index(),并且框架将从该控制器的views目录中选择WEB-INF / views / article / index.ftl模板。 同样,对于任何其他操作,将根据操作名称选择视图。
这并不总是我们想要的。 有时我们可能希望基于内部业务逻辑返回一些视图。 在这种情况下,我们可以使用父级org.javalite.activeweb.AppController类中的render()方法控制该过程:
1 2 3 | public void index() { render("articles"); } |
请注意,自定义视图的位置也应位于该控制器的同一视图目录中。 如果不是这种情况,请在模板名称之前加上模板所在的目录名称,并将其传递给render()方法:
1 | render("/common/error"); |
6.3。 具有数据的视图
要将数据发送到视图,org.javalite.activeweb.AppController提供了view()方法:
1 | view("articles", articleService.getArticles()); |
这需要两个参数。 首先,用于访问模板中对象的对象名称,其次是包含数据的对象。
我们还可以使用assign()方法将数据传递给视图。 view()和assign()方法之间绝对没有区别–我们可以选择其中任何一种:
1 | assign("article", articleService.search(keyword)); |
让我们在模板中映射数据:
1 2 3 4 5 6 7 8 9 10 11 | <@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作为依赖项管理框架。
假设我们的应用程序中需要一个服务类; 这会将业务逻辑与控制器分开。
首先创建一个服务接口:
1 2 3 4 5 6 |
并执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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模块:
1 2 3 4 5 6 7 8 | public class ArticleServiceModule extends AbstractModule { @Override protected void configure() { bind(ArticleService.class).to(ArticleServiceImpl.class) .asEagerSingleton(); } } |
最后,根据需要在应用程序上下文中注册并将其注入到控制器中:
1 2 3 4 5 6 7 8 9 | public class AppBootstrap extends Bootstrap { public void init(AppContext context) { } public Injector getInjector() { return Guice.createInjector(new ArticleServiceModule()); } } |
请注意,此配置类名称必须为AppBootstrap,并且应位于app.config包中。
最后,这是我们将其注入控制器的方法:
1 2 | @Inject private ArticleService articleService; |
8.测试
ActiveWeb应用程序的单元测试是使用JavaLite的JSpec库编写的。
我们将使用JSpec中的org.javalite.activeweb.ControllerSpec类来测试我们的控制器,并按照相似的约定命名测试类:
1 2 3 | public class ArticleControllerSpec extends ControllerSpec { // ... } |
注意,该名称与它正在测试的控制器相似,最后以" Spec"结尾。
这是测试用例:
1 2 3 4 5 6 | @Test public void whenReturnedArticlesThenCorrect() { request().get("index"); a(responseContent()) .shouldContain("<td>Introduction to Mule</td>"); } |
注意,request()方法模拟了对控制器的调用,相应的HTTP方法get()将操作名称作为参数。
我们还可以使用params()方法将参数传递给控制器:
1 2 3 4 5 6 | @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插件:
1 2 3 4 5 6 7 8 9 10 11 | ... <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> ... |
插件的最新版本在这里。
现在,最后–我们可以启动它:
1 | mvn jetty:run |
10.结论
在本文中,我们了解了ActiveWeb框架的基本概念和约定。 除了这些之外,该框架还具有比我们在此讨论的功能更多的功能。
请参阅官方文档以了解更多详细信息。
而且,与往常一样,本文中使用的示例代码可从GitHub上获得。