1. Overview
1.概述
In this article, we’ll have a look at VRaptor, a simple and straightforward Java MVC web framework which utilizes Java Contexts and Dependency Injection technology and is easy to grasp.
在本文中,我们将看看VRaptor,这是一个简单明了的Java MVC网络框架,它利用了Java Contexts和依赖注入技术,易于掌握。
Just like Spring – it relies heavily on annotations and works great with Hibernate.
就像Spring一样–它在很大程度上依赖于注解,与Hibernate配合得很好。
It also comes with some useful plugins – such as for internalization and unit testing.
它还配备了一些有用的插件–如用于内部化和单元测试。
So, let’s explore the different components of VRaptor and create a sample project.
因此,让我们来探索VRaptor的不同组件,并创建一个示例项目。
2. Maven Dependencies and Setup
2.Maven的依赖性和设置
One quick way to get up and running is to download the vraptor-blank-project-distribution from the official repository.
一个快速启动和运行的方法是,从官方资源库下载vraptor-blank-project-distribution。
The blank project is just a skeleton that can be fleshed out to become a full-fledged web application of choice.
空白项目只是一个骨架,可以充实成为一个成熟的网络应用的选择。
After downloading and unzipping the project, let’s rename the directory to vraptor (or any other name).
下载并解压项目后,让我们将目录重命名为vraptor(或任何其他名称)。
The directory should contain:
该目录应包含。
- src/
- pom.xml
- and README.md
The project is Maven-based and comes with tomcat7 Maven plugin which provides the servlet container for running the application.
该项目基于Maven,配有tomcat7 Maven插件,为运行应用程序提供Servlet容器。
It also comes with a default IndexController that has just one method – index().
它还带有一个默认的IndexController,只有一个方法–index()。
By default, the view to be rendered by this method is located in webapp/WEB-INF/jsp/index/index.jsp – this follows the convention WEB-INF/jsp/controller_name/method_name.
默认情况下,这个方法要渲染的视图位于webapp/WEB-INF/jsp/index/index.jsp–这遵循了WEB-INF/jsp/controller_name/method_name.的惯例。
To start the server, we’ll execute the command mvn tomcat7:run from the root of the project.
为了启动服务器,我们将从项目的根部执行mvn tomcat7:run命令。
If successful, if we visit http://localhost:8080, a browser will display “It works!! VRaptor!“.
如果成功,如果我们访问http://localhost:8080,,浏览器将显示”它成功了!VRaptor!“。
If we face the “java.lang.LinkageError: loader constraint violation”, then, we have to modify the following dependencies in pom.xml:
如果我们面临”java.lang.LinkageError: loader constraint violation”,那么,我们必须修改pom.xml中的以下依赖。
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-core</artifactId>
<version>2.1.2.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.el</groupId>
<artifactId>jboss-el-api_3.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core-impl</artifactId>
<version>2.1.2.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.el</groupId>
<artifactId>jboss-el-api_3.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
The culprit is the el-api that is included in weld-servlet-core and weld-core-impl with compile scope; this leads to a dependency clash.
罪魁祸首是包含在weld-servlet-core和weld-core-impl中的el-api,其范围为compile;这导致了依赖性冲突。
The following dependencies will be needed along the line, so let’s include them in pom.xml:
下面的依赖将被沿用,所以让我们在pom.xml中包含它们。
<dependency>
<groupId>br.com.caelum.vraptor</groupId>
<artifactId>vraptor-freemarker</artifactId>
<version>4.1.0-RC3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.8-dmr</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.27-incubating</version>
</dependency>
The latest version of vraptor-freemarker, mysql-connector-java, and freemarker artifacts can be found in Maven Central.
最新版本的vraptor-freemarker,mysql-connector-java和freemarker工件可以在Maven中心找到。
Now that we’re good to go, let’s build a simple blog site.
现在我们已经准备好了,让我们建立一个简单的博客网站。
3. Hibernate Support
3.Hibernate支持
VRaptor provides various plugins for interacting with databases, one of them is vraptor-hibernate which works with Hibernate 4.
VRaptor提供了各种与数据库交互的插件,其中一个是vraptor-hibernate,它与Hibernate 4一起工作。
The plugin makes the Hibernate’s SessionFactory bean available at runtime via CDI.
该插件使Hibernate的SessionFactory bean在运行时通过CDI可用。
With the plugin in place, we need a standard Hibernate configuration file – an example can be found in the repository.
有了这个插件,我们需要一个标准的Hibernate配置文件–一个例子可以在资源库中找到。
VRaptor uses a technique called Producers to make objects available for DI management. More details about this here.
VRaptor使用一种叫做Producers的技术来使对象可用于DI管理。关于这个的更多细节这里。
4. Defining Web Routes in VRaptor
4.在VRaptor中定义网络路由
In VRaptor, route definitions reside in controllers which are simply @Controller-annotated Java objects – just like in Spring.
在VRaptor中,路由定义存在于控制器中,控制器是简单的@Controller注释的Java对象–就像Spring中一样。
@Path annotation is used for mapping a request path to a particular controller and @Get, @Post, @Put, @Delete and @Patch annotations are used for specifying HTTP request types.
@Path注解用于将请求路径映射到特定的控制器,@Get、@Post、@Put、@Delete和@Patch注解用于指定HTTP请求类型。
Route mapping configuration looks similar to JAX-RS’ way but doesn’t implement the standard officially.
路由映射配置看起来与JAX-RS的方式类似,但没有正式实现标准。。
Additionally, when defining a path, it’s possible to specify a path variable in curly braces:
此外,在定义路径时,可以在大括号中指定一个路径变量。
@Get("/posts/{id}")
The value of id can then be accessed inside a controller method:
然后可以在控制器方法中访问id的值。
@Get("/posts/{id}")
public void view(int id) {
// ...
}
When a form is submitted to a particular route, VRaptor can automatically populate an object with the form-data submitted.
当一个表单被提交到一个特定的途径时,VRaptor可以用提交的表单数据自动填充一个对象。
Let’s see this in action in the next section of the article.
让我们在文章的下一节中看看这一点的作用。
5. Views and Template Engine
5.视图和模板引擎
By default, views can be implemented using JSP. However, other template engines can be used as well – in this article, we’ll work with Freemarker.
默认情况下,视图可以使用JSP来实现。然而,也可以使用其他模板引擎–在这篇文章中,我们将使用Freemarker。
Let’s start by creating index.ftl and saving it in the default view directory (src/main/resources/templates):
让我们先创建index.ftl并将其保存在默认视图目录(src/main/resources/templates)中。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>VRaptor Blank Project</title>
</head>
<body>
It works!! ${variable}
</body>
</html>
Now, we can use the defined view with a FreemarkerView class for view rendering:
现在,我们可以使用定义好的视图与FreemarkerView类来进行视图渲染。
@Path("/")
public void index() {
result.include("variable", "VRaptor!");
result.use(FreemarkerView.class).withTemplate("index");
}
The Result object holds model state – it has methods for redirecting to another page, URL, or a controller method; it can be injected into the controller using CDI.
Result对象持有模型状态–它有重定向到另一个页面、URL或控制器方法的方法;它可以使用CDI注入到控制器。
In our example, the variable gets resolved by Freemarker. Thus ${variable} placeholder in index.ftl gets replaced with the “VRaptor!”.
在我们的例子中,变量被Freemarker解决。因此${variable}占位符在index.ftl中被替换为 “VRaptor!”。
More advanced usages are documented here.
更多的高级用法被记录在这里。
6. Form Submission Handling Example
6.表格提交处理实例
Let’s see how can we handle form submissions with validation:
让我们看看如何处理带有验证功能的表单提交。
@Post("/post/add")
public void add(Post post) {
post.setAuthor(userInfo.getUser());
validator.validate(post);
if(validator.hasErrors()) {
result.include("errors", validator.getErrors());
}
validator.onErrorRedirectTo(this).addForm();
Object id = postDao.add(post);
if(Objects.nonNull(id)) {
result.include("status", "Post Added Successfully");
result.redirectTo(IndexController.class).index();
} else {
result.include(
"error", "There was an error creating the post. Try Again");
result.redirectTo(this).addForm();
}
}
The Post object gets validated first using Java bean validation before being persisted into the database using postDao.add().
在使用postDao.add()持久化到数据库之前,Post对象首先被使用Java Bean验证进行验证。
The fields of the Post object are populated automatically from values of the submitted form-data – which correspond to the form’s input fields in the view file.
Post对象的字段是由提交的表单数据的值自动填充的–它对应于视图文件中的表单输入字段。
Note that the name of the input field has to be prefixed with the name of the object in lowercase.
请注意,输入字段的名称必须以小写的对象名称为前缀。
For example, the view that’s responsible for adding a new post has input fields: post.title and post.post which correspond to fields title and post in Post.java respectively:
例如,负责添加一个新帖子的视图有输入字段。post.title和post.post分别对应于Post.java中的title和post字段。
<input type="text" class="form-control" placeholder="Title"
id="title" name="post.title" required />
<textarea rows="10" class="form-control" placeholder="Post"
id="post" name="post.post" required></textarea>
The complete add.ftl file can be found in the source code.
完整的add.ftl文件可以在源代码中找到。
If there is an error in the form submission, the error message gets included and user redirected to the same add() method:
如果在表单提交中出现错误,错误信息会被包含在内,用户会被重定向到同一个add()方法。
if(validator.hasErrors()) {
result.include("errors", validator.getErrors());
}
validator.onErrorRedirectTo(this).addForm();
7. Conclusion
7.结论
In conclusion, we’ve looked at VRaptor at a glance and saw how basic MVC functionality can be achieved.
总之,我们已经对VRaptor有了一个初步的了解,看到了基本的MVC功能是如何实现的。
The documentation contains more detail about the framework as well as available plugins.
文档包含有关框架以及可用插件的更多细节。
The complete source code, including a sample database.sql, is available over on Github.
完整的源代码,包括一个样本database.sql,可在Github上获得over。