1. Overview
1.概述
Nowadays, from social networking to banking, healthcare to government services, all activities are available online. Therefore, they rely heavily on web applications.
如今,从社交网络到银行,从医疗保健到政府服务,所有活动都可以在网上进行。因此,他们在很大程度上依赖网络应用。
A web application enables users to consume/enjoy the online services provided by a company. At the same time, it acts as an interface to the backend software.
网络应用程序使用户能够消费/享受一个公司提供的在线服务。同时,它作为后台软件的一个接口。
In this introductory tutorial, we’ll explore the Apache Tapestry web framework and create a simple web application using the basic features that it provides.
在这个入门教程中,我们将探索Apache Tapestry网络框架,并使用它提供的基本功能创建一个简单的网络应用。
2. Apache Tapestry
2.阿帕奇挂毯
Apache Tapestry is a component-based framework for building scalable web applications.
Apache Tapestry是一个基于组件的框架,用于构建可扩展的网络应用。
It follows the convention-over-configuration paradigm and uses annotations and naming conventions for configurations.
它遵循convention-over-configuration范式,并为配置使用注释和命名约定。
All the components are simple POJOs. At the same time, they are developed from scratch and have no dependencies on other libraries.
所有的组件都是简单的POJO。同时,它们是从零开始开发的,没有对其他库的依赖性。
Along with Ajax support, Tapestry also has great exception reporting capabilities. It provides an extensive library of built-in common components as well.
除了对Ajax的支持,Tapestry还具有强大的异常报告能力。它还提供了一个广泛的内置通用组件库。
Among other great features, a prominent one is the hot reloading of the code. Therefore, using this feature, we can see the changes instantly in the development environment.
在其他伟大的功能中,一个突出的功能是代码的热重载。因此,使用这一功能,我们可以在开发环境中即时看到变化。
3. Setup
3.设置
Apache Tapestry requires a simple set of tools to create a web application:
Apache Tapestry需要一套简单的工具来创建一个网络应用。
- Java 1.6 or later
- Build Tool (Maven or Gradle)
- IDE (Eclipse or IntelliJ)
- Application Server (Tomcat or Jetty)
In this tutorial, we’ll use the combination of Java 8, Maven, Eclipse, and Jetty Server.
在本教程中,我们将使用Java 8、Maven、Eclipse和Jetty服务器的组合。
To set up the latest Apache Tapestry project, we’ll use Maven archetype and follow the instructions provided by the official documentation:
要设置最新的Apache Tapestry项目,我们将使用Maven原型并遵循官方文档提供的说明。
$ mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org
Or, if we have an existing project, we can simply add the tapestry-core Maven dependency to the pom.xml:
或者,如果我们有一个现有的项目,我们可以简单地将tapestry-coreMaven依赖性添加到pom.xml。
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-core</artifactId>
<version>5.4.5</version>
</dependency>
Once we’re ready with the setup, we can start the application apache-tapestry by the following Maven command:
设置完毕后,我们可以通过以下Maven命令启动应用程序apache-tapestry。
$ mvn jetty:run
By default, the app will be accessible at localhost:8080/apache-tapestry:
默认情况下,该应用程序将在localhost:8080/apache-tapestry被访问。
4. Project Structure
4.项目结构
Let’s explore the project layout created by Apache Tapestry:
让我们探讨一下Apache Tapestry创建的项目布局。
We can see a Maven-like project structure, along with a few packages based on conventions.
我们可以看到一个类似Maven的项目结构,以及一些基于惯例的包。
The Java classes are placed in src/main/java and categorized as components, pages, and services.
Java类被放置在src/main/java中,并被分类为组件、页面和服务。
Likewise, src/main/resources hold our templates (similar to HTML files) — these have the .tml extension.
同样,src/main/resources存放我们的模板(类似于HTML文件)–这些模板有.tml扩展名。
For every Java class placed under components and pages directories, a template file with the same name should be created.
对于放在components和pages目录下的每一个Java类,都应该创建一个同名的模板文件。
The src/main/webapp directory contains resources like images, stylesheets, and JavaScript files. Similarly, testing files are placed in src/test.
src/main/webapp目录包含图片、样式表和JavaScript文件等资源。同样地,测试文件被放在src/test中。
Last, src/site will contain the documentation files.
最后,src/site将包含文档文件。
For a better idea, let’s take a look at the project structure opened in Eclipse IDE:
为了更好地了解情况,让我们看一下在Eclipse IDE中打开的项目结构。
5. Annotations
5.注释
Let’s discuss a few handy annotations provided by Apache Tapestry for day-to-day use. Going forward, we’ll use these annotations in our implementations.
让我们讨论一下Apache Tapestry提供的几个方便的注解,供日常使用。今后,我们将在我们的实现中使用这些注释。
5.1. @Inject
5.1 @Inject
The @Inject annotation is available in the org.apache.tapestry5.ioc.annotations package and provides an easy way to inject dependencies in Java classes.
@Inject注解在org.apache.tapestry5.ioc.annotations包中可用,它提供了一种在Java类中注入依赖的简便方法。
This annotation is quite handy to inject an asset, block, resource, and service.
这个注解对于注入资产、区块、资源和服务是非常方便的。
5.2. @InjectPage
5.2@InjectPage
Available in the org.apache.tapestry5.annotations package, the @InjectPage annotation allows us to inject a page into another component. Also, the injected page is always a read-only property.
org.apache.tapestry5.annotations包中有,@InjectPage注解允许我们将一个页面注入另一个组件中。另外,注入的页面总是一个只读的属性。
5.3. @InjectComponent
5.3.@InjectComponent
Similarly, the @InjectComponent annotation allows us to inject a component defined in the template.
同样,@InjectComponent注解允许我们注入一个在模板中定义的组件。
5.4. @Log
5.4. @Log
The @Log annotation is available in the org.apache.tapestry5.annotations package and is handy to enable the DEBUG level logging on any method. It logs method entry and exit, along with parameter values.
@Log注解在org.apache.tapestry5.annotations包中可用,它可以方便地在任何方法上启用DEBUG级日志。它记录了方法的进入和退出,以及参数值。
5.5. @Property
5.5.@Property
Available in the org.apache.tapestry5.annotations package, the @Property annotation marks a field as a property. At the same time, it automatically creates getters and setters for the property.
org.apache.tapestry5.annotations包中有,@Property注解将一个字段标记为一个属性。同时,它自动为该属性创建getters和setters。
5.6. @Parameter
5.6. @参数
Similarly, the @Parameter annotation denotes that a field is a component parameter.
类似地,@Parameter注解表示一个字段是一个组件参数。
6. Page
6.页码
So, we’re all set to explore the basic features of the framework. Let’s create a new Home page in our app.
所以,我们已经准备好探索该框架的基本功能了。让我们在我们的应用程序中创建一个新的Home页面。
First, we’ll define a Java class Home in the pages directory in src/main/java:
首先,我们将在src/main/java的pages目录下定义一个Java类Home。
public class Home {
}
6.1. Template
6.1.模板
Then, we’ll create a corresponding Home.tml template in the pages directory under src/main/resources.
然后,我们将在src/main/resources下的pages目录中创建一个相应的Home.tmltemplate。
A file with the extension .tml (Tapestry Markup Language) is similar to an HTML/XHTML file with XML markup provided by Apache Tapestry.
扩展名为.tml(Tapestry标记语言)的文件类似于Apache Tapestry提供的带有XML标记的HTML/XHTML文件。
For instance, let’s have a look at the Home.tml template:
例如,让我们看一下Home.tml模板。
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>apache-tapestry Home</title>
</head>
<body>
<h1>Home</h1>
</body>
</html>
Voila! Simply by restarting the Jetty server, we can access the Home page at localhost:8080/apache-tapestry/home:
好了!只要重新启动Jetty服务器,我们就可以访问Home页面,地址是localhost:8080/apache-tapestry/home。
6.2. Property
6.2 财产
Let’s explore how to render a property on the Home page.
让我们探讨一下如何在Home页面上渲染一个属性。
For this, we’ll add a property and a getter method in the Home class:
为此,我们将在Home类中添加一个属性和一个getter方法。
@Property
private String appName = "apache-tapestry";
public Date getCurrentTime() {
return new Date();
}
To render the appName property on the Home page, we can simply use ${appName}.
要在首页页上呈现appName属性,我们可以简单地使用${appName}。
Similarly, we can write ${currentTime} to access the getCurrentTime method from the page.
同样地,我们可以写${currentTime}来访问页面中的getCurrentTime方法。
6.3. Localization
6.3.定位
Apache Tapestry provides integrated localization support. As per convention, a page name property file keeps the list of all the local messages to render on the page.
Apache Tapestry提供集成的本地化支持。按照惯例,页面名称属性文件保留了要在页面上呈现的所有本地信息的列表。
For instance, we’ll create a home.properties file in the pages directory for the Home page with a local message:
例如,我们将在pages目录下为Home页创建一个home.properties文件,该文件有一个本地信息。
introMsg=Welcome to the Apache Tapestry Tutorial
The message properties are different from the Java properties.
消息属性与Java属性不同。
For the same reason, the key name with the message prefix is used to render a message property — for instance, ${message:introMsg}.
出于同样的原因,带有message前缀的键名被用来呈现一个消息属性–例如,${message:introMsg}.。
6.4. Layout Component
6.4.布局组件
Let’s define a basic layout component by creating the Layout.java class. We’ll keep the file in the components directory in src/main/java:
让我们通过创建Layout.java类来定义一个基本布局组件。我们将把这个文件放在src/main/java的components目录下。
public class Layout {
@Property
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String title;
}
Here, the title property is marked required, and the default prefix for binding is set as literal String.
这里,title属性被标记为必填项,绑定的默认前缀被设置为字面的String。
Then, we’ll write a corresponding template file Layout.tml in the components directory in src/main/resources:
然后,我们将在src/main/resources的components目录下写一个相应的模板文件Layout.tml。
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>${title}</title>
</head>
<body>
<div class="container">
<t:body />
<hr/>
<footer>
<p>© Your Company</p>
</footer>
</div>
</body>
</html>
Now, let’s use the layout on the home page:
现在,让我们在home页面上使用layout。
<html t:type="layout" title="apache-tapestry Home"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<h1>Home! ${appName}</h1>
<h2>${message:introMsg}</h2>
<h3>${currentTime}</h3>
</html>
Note, the namespace is used to identify the elements (t:type and t:body) provided by Apache Tapestry. At the same time, the namespace also provides components and attributes.
注意,命名空间是用来识别Apache Tapestry提供的元素(t:type和t:body)。同时,该命名空间还提供了组件和属性。
Here, the t:type will set the layout on the home page. And, the t:body element will insert the content of the page.
这里,t:type将设置layout在home页面上。而且,t:body元素将插入页面的内容。
Let’s take a look at the Home page with the layout:
让我们看一下带有布局的主页页。
7. Form
7.形状
Let’s create a Login page with a form, to allow users to sign-in.
让我们创建一个带有表单的登录页面,以允许用户登录。
As already explored, we’ll first create a Java class Login:
正如已经探讨过的,我们将首先创建一个Java类Login。
public class Login {
// ...
@InjectComponent
private Form login;
@Property
private String email;
@Property
private String password;
}
Here, we’ve defined two properties — email and password. Also, we’ve injected a Form component for the login.
在这里,我们定义了两个属性 – email 和 password。此外,我们还为登录注入了一个Form组件。
Then, let’s create a corresponding template login.tml:
然后,让我们创建一个相应的模板login.tml。
<html t:type="layout" title="apache-tapestry com.example"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:p="tapestry:parameter">
<t:form t:id="login">
<h2>Please sign in</h2>
<t:textfield t:id="email" placeholder="Email address"/>
<t:passwordfield t:id="password" placeholder="Password"/>
<t:submit class="btn btn-large btn-primary" value="Sign in"/>
</t:form>
</html>
Now, we can access the login page at localhost:8080/apache-tapestry/login:
现在,我们可以在localhost:8080/apache-tapestry/login上访问login页面。
8. Validation
8.审定
Apache Tapestry provides a few built-in methods for form validation. It also provides ways to handle the success or failure of the form submission.
Apache Tapestry为表单验证提供了一些内置方法。它还提供了处理表单提交成功或失败的方法。
The built-in method follows the convention of the event and the component name. For instance, the method onValidationFromLogin will validate the Login component.
内置方法遵循事件和组件名称的惯例。例如,方法onValidationFromLogin将验证Login组件。
Likewise, methods like onSuccessFromLogin and onFailureFromLogin are for success and failure events respectively.
同样,像onSuccessFromLogin和onFailureFromLogin这样的方法分别针对成功和失败事件。
So, let’s add these built-in methods to the Login class:
所以,让我们把这些内置的方法添加到Login类中。
public class Login {
// ...
void onValidateFromLogin() {
if (email == null)
System.out.println("Email is null);
if (password == null)
System.out.println("Password is null);
}
Object onSuccessFromLogin() {
System.out.println("Welcome! Login Successful");
return Home.class;
}
void onFailureFromLogin() {
System.out.println("Please try again with correct credentials");
}
}
9. Alerts
9.警报
Form validation is incomplete without proper alerts. Not to mention, the framework also has built-in support for alert messages.
没有适当的警报,表单验证是不完整的。更不用说,该框架还内置了对警报信息的支持。
For this, we’ll first inject the instance of the AlertManager in the Login class to manage the alerts. Then, replace the println statements in existing methods with the alert messages:
为此,我们将首先在Login类中注入AlertManager的实例,以管理警报。然后,用警报信息替换现有方法中的println语句。
public class Login {
// ...
@Inject
private AlertManager alertManager;
void onValidateFromLogin() {
if(email == null || password == null) {
alertManager.error("Email/Password is null");
login.recordError("Validation failed"); //submission failure on the form
}
}
Object onSuccessFromLogin() {
alertManager.success("Welcome! Login Successful");
return Home.class;
}
void onFailureFromLogin() {
alertManager.error("Please try again with correct credentials");
}
}
Let’s see the alerts in action when the login fails:
让我们看看登录失败时的警示作用。
10. Ajax
10.阿贾克斯
So far, we’ve explored the creation of a simple home page with a form. At the same time, we’ve seen the validations and support for alert messages.
到目前为止,我们已经探讨了如何创建一个带有表单的简单home页面。同时,我们也看到了验证和对警告信息的支持。
Next, let’s explore the Apache Tapestry’s built-in support for Ajax.
接下来,让我们探讨一下Apache Tapestry对Ajax的内置支持。
First, we’ll inject the instance of the AjaxResponseRenderer and Block component in the Home class. Then, we’ll create a method onCallAjax for processing the Ajax call:
首先,我们将在Home类中注入AjaxResponseRenderer和Block组件的实例。然后,我们将创建一个方法onCallAjax来处理Ajax调用。
public class Home {
// ....
@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
@Inject
private Block ajaxBlock;
@Log
void onCallAjax() {
ajaxResponseRenderer.addRender("ajaxZone", ajaxBlock);
}
}
Also, we need to make a few changes in our Home.tml.
另外,我们需要在我们的Home.tml中做一些修改。
First, we’ll add the eventLink to invoke the onCallAjax method. Then, we’ll add a zone element with id ajaxZone to render the Ajax response.
首先,我们将添加eventLink来调用onCallAjax方法。然后,我们将添加一个zone元素,其id为ajaxZone以呈现Ajax响应。
Last, we need to have a block component that will be injected in the Home class and rendered as Ajax response:
最后,我们需要有一个块状组件,它将被注入到Home 类中,并作为Ajax响应呈现。
<p><t:eventlink event="callAjax" zone="ajaxZone" class="btn btn-default">Call Ajax</t:eventlink></p>
<t:zone t:id="ajaxZone"></t:zone>
<t:block t:id="ajaxBlock">
<hr/>
<h2>Rendered through Ajax</h2>
<p>The current time is: <strong>${currentTime}></p>
</t:block>
Let’s take a look at the updated home page:
让我们来看看更新后的home页面。
Then, we can click the Call Ajax button and see the ajaxResponseRenderer in action:
然后,我们可以点击Call Ajax按钮,看到ajaxResponseRenderer在运行。
11. Logging
11.伐木
To enable the built-in logging feature, the instance of the Logger is required to be injected. Then, we can use it to log at any level like TRACE, DEBUG, and INFO.
为了启用内置的日志功能,需要注入Logger的实例。然后,我们可以用它来记录任何级别的日志,如TRACE、DEBUG和INFO。
So, let’s make the required changes in the Home class:
因此,让我们在Home 类中进行必要的修改。
public class Home {
// ...
@Inject
private Logger logger;
void onCallAjax() {
logger.info("Ajax call");
ajaxResponseRenderer.addRender("ajaxZone", ajaxBlock);
}
}
Now, when we click the Call Ajax button, the logger will log at the INFO level:
现在,当我们点击Call Ajax按钮时,logger将在INFO级别记录。
[INFO] pages.Home Ajax call
12. Conclusion
12.结语
In this article, we’ve explored the Apache Tapestry web framework.
在这篇文章中,我们已经探讨了Apache Tapestry网络框架。
To begin with, we’ve created a quickstart web application and added a Home page using basic features of Apache Tapestry, like components, pages, and templates.
首先,我们使用Apache Tapestry的基本功能,如组件、页面和模板,创建了一个快速入门的Web应用程序并添加了一个主页页面。
Then, we’ve examined a few handy annotations provided by Apache Tapestry to configure a property and component/page injection.
然后,我们研究了Apache Tapestry提供的一些方便的注解,以配置一个属性和组件/页面注入。
Last, we’ve explored the built-in Ajax and logging support provided by the framework.
最后,我们探讨了该框架所提供的内置Ajax和日志支持。
As usual, all the code implementations are available over on GitHub.
像往常一样,所有的代码实现都可以在GitHub上找到,。