1. 框架概述

VRaptor 是一个简单直接的 Java MVC Web 框架,它基于 Java 上下文和依赖注入(CDI)技术构建,学习曲线平缓。和 Spring 类似,它重度依赖注解且与 Hibernate 配合默契

框架还提供了一些实用插件,比如国际化支持和单元测试工具。接下来我们将深入探索 VRaptor 的核心组件并构建一个示例项目。

2. Maven 依赖与环境搭建

快速启动的最佳方式是从官方仓库下载 vraptor-blank-project-distribution。这个空白项目只是一个骨架,可以扩展为完整的 Web 应用。

下载解压后,将目录重命名为 vraptor(或其他名称)。目录应包含:

  • src/
  • pom.xml
  • README.md

项目基于 Maven,内置了 tomcat7 Maven 插件作为 Servlet 容器。默认包含一个 IndexController,仅有一个 index() 方法。该方法渲染的视图默认位于 webapp/WEB-INF/jsp/index/index.jsp,遵循 WEB-INF/jsp/控制器名/方法名 的约定。

执行 mvn tomcat7:run 启动服务器。成功后访问 http://localhost:8080,浏览器会显示 "It works!! VRaptor!"。

⚠️ 踩坑提示:如果遇到 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>

问题根源是 weld-servlet-coreweld-core-impl 中包含的 el-api 依赖冲突。后续需要添加以下依赖:

<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>

最新版本可在 Maven Central 查找。环境就绪后,我们开始构建一个简单的博客系统。

3. Hibernate 集成

VRaptor 提供多种数据库交互插件,其中 vraptor-hibernate 支持 Hibernate 4。该插件通过 CDI 在运行时提供 Hibernate 的 SessionFactory Bean

配置插件后,需要标准的 Hibernate 配置文件(示例见仓库)。VRaptor 使用 Producer 技术将对象纳入 DI 管理,详见官方文档

4. Web 路由定义

在 VRaptor 中,路由定义位于控制器(用 @Controller 注解的 Java 对象)中,类似 Spring:

  • @Path 映射请求路径
  • @Get/@Post/@Put/@Delete/@Patch 指定 HTTP 方法

路由配置类似 JAX-RS 但未实现其标准。定义路径时可用花括号指定路径变量:

@Get("/posts/{id}")

控制器方法可直接访问变量值:

@Get("/posts/{id}")
public void view(int id) {
    // ...
}

表单提交时,VRaptor 能自动将表单数据填充到对象中,后续章节将演示具体用法。

5. 视图与模板引擎

默认使用 JSP 实现视图,但也可集成其他模板引擎(本文使用 Freemarker)。创建 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>

通过 FreemarkerView 类渲染视图:

@Path("/")
public void index() {
    result.include("variable", "VRaptor!");
    result.use(FreemarkerView.class).withTemplate("index");
}

Result 对象管理模型状态,支持页面/URL/控制器方法重定向,可通过 CDI 注入。示例中 variable 被 Freemarker 解析,替换 index.ftl 中的占位符。高级用法见文档

6. 表单提交处理示例

带验证的表单提交处理:

@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();
    }
}

Post 对象先通过 Java Bean Validation 验证,再通过 postDao.add() 持久化。对象字段由表单数据自动填充——注意输入字段名必须用小写对象名作为前缀

例如添加文章的表单字段:

<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>

完整 add.ftl 见源码。提交出错时:

if(validator.hasErrors()) {
    result.include("errors", validator.getErrors());
}
validator.onErrorRedirectTo(this).addForm();

错误信息会被包含并重定向回表单页面。

7. 总结

本文概述了 VRaptor 的核心功能,展示了基本 MVC 实现方式。更多细节和插件请参考官方文档

完整源码(含示例 database.sql)见 GitHub 仓库


原始标题:Introduction to VRaptor in Java