杰瑞科技汇

Play Framework教程如何快速上手?

Play Framework 综合教程

Play Framework 是一个用于构建现代、可扩展、高性能 Web 应用的开源框架,它以其“无状态”、“非阻塞”和“约定优于配置”的理念而闻名,非常适合构建 RESTful API 和实时应用。

Play Framework教程如何快速上手?-图1
(图片来源网络,侵删)

第一部分:入门准备

什么是 Play Framework?

  • 核心特点:
    • 无状态: 服务器不存储客户端的会话状态,这使得应用更容易水平扩展,会话数据通常存储在客户端(加密 Cookie)或外部存储(如 Redis)中。
    • 非阻塞 & 异步: 基于 Akka 和 Reactive Streams,Play 能够高效处理大量并发连接,非常适合 I/O 密集型应用。
    • 约定优于配置: 遵循一套清晰的目录结构和命名约定,让你能专注于业务逻辑,而不是繁琐的配置。
    • 实时能力: 内置 WebSocket 和 Server-Sent Events (SSE) 支持,便于构建实时功能(如聊天室、仪表盘)。
    • 热重载: 开发时,代码修改后应用会自动重启,极大地提升了开发效率。
    • 多语言支持: 官方支持 Java 和 Scala。

环境准备

在开始之前,请确保你的系统已安装以下工具:

  • JDK 17 或更高版本: Play 3.x 需要 Java 17+,你可以从 Adoptium (Eclipse Temurin) 下载。
  • Build 工具 (二选一):
    • 强烈推荐 Gradle: Play 3.x 对 Gradle 的支持是第一位的,请安装 Gradle
    • 备选 SBT: Scala 的构建工具,如果你更偏向 Scala,可以安装 SBT
  • IDE (推荐):
    • IntelliJ IDEA: 对 Play 和 Scala/Java 的支持最好。
    • VS Code: 配合合适的插件(如 Java Extension Pack)也能有不错的体验。

第二部分:创建你的第一个 Play 项目

我们将使用 Giter8 命令行工具来快速生成一个标准的 Play 项目骨架。

安装 Giter8

如果你没有安装 Giter8,可以通过以下命令安装(需要先安装 coursier):

cs install g8

创建项目

打开终端,运行以下命令,它会从官方模板创建一个新项目。

Play Framework教程如何快速上手?-图2
(图片来源网络,侵删)
g8 playframework/play-java-seed.g8

命令会提示你输入一些信息:

  • organization_name (e.g., com.example)
  • project_name (e.g., my-first-play-app)
  • package_name (e.g., com.example)
  • play_version (e.g., x.x)

输入完毕后,按回车,Giter8 会在当前目录下创建一个以你的项目名命名的文件夹。

进入项目并运行

cd my-first-play-app
./gradlew run
  • ./gradlew 是 Gradle 的 Wrapper,无需全局安装 Gradle。
  • run 命令会启动 Play 应用。

首次运行时,Gradle 会下载所需的依赖,这可能需要几分钟,完成后,你会看到类似以下的输出:

--- (Running the application from /path/to/your/project, using CWD as base directory) ---
Listening for transport dt_socket at address: 5005
[info] p.c.s.AkkaHttpServer - Listening on address /0.0.0.0:9000

打开你的浏览器,访问 http://localhost:9000,你应该能看到 Play 的欢迎页面。

Play Framework教程如何快速上手?-图3
(图片来源网络,侵删)

体验热重载

保持应用运行,打开 app/controllers/HomeController.java 文件,修改其中的消息,

public Result index(Http.Request request) {
    return ok("Hello, my first Play app! This is a change."); // 修改这里的文本
}

保存文件,你会看到控制台应用自动重启,刷新浏览器,你会看到更新后的消息,这就是 Play 的热重载功能!


第三部分:核心概念详解

一个 Play 应用的核心结构如下:

my-first-play-app/
├── app/
│   ├── controllers/    # 控制器:处理 HTTP 请求
│   ├── models/         # 模型:数据结构(可选,如 JPA 实体)
│   ├── views/          # 视图:渲染 HTML 页面(仅用于 Web 应用)
│   └── Application.java # 应用入口点
├── conf/
│   ├── application.conf # 应用配置文件
│   └── routes          # 路由定义文件
├── build.gradle        # Gradle 构建文件
└── public/             # 静态资源 (CSS, JS, 图片等)

路由

conf/routes 文件是 Play 的“交通警察”,它定义了 URL 如何映射到控制器的方法。

格式: HTTP_METHOD /path/to/controller -> controllers.ControllerName.actionMethod

示例 (conf/routes):

# 首页
GET     /                           controllers.HomeController.index
# 一个带路径参数的页面,/hello/World
GET     /hello/:name                controllers.HomeController.sayHello(name: String)
# 一个带查询参数的页面,/items?id=123
GET     /items                      controllers.HomeController.getItem(id: Long)
  • name 是一个路径参数,它会作为参数传递给控制器方法。
  • id: Long 是一个查询参数,Play 会自动尝试将 id 的值转换为 Long 类型。

控制器

控制器是业务逻辑的核心,它接收 HTTP 请求,进行处理,并返回一个 Result 对象。Result 是对 HTTP 响应的封装,可以是 HTML、JSON、重定向等。

示例 (app/controllers/HomeController.java):

package controllers;
import play.mvc.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public class HomeController extends Controller {
    // 同步方法,返回简单的 HTML 或文本
    public Result index(Http.Request request) {
        // request 对象包含了所有关于 HTTP 请求的信息
        return ok("Hello, my first Play app!");
    }
    // 带路径参数的方法
    public Result sayHello(String name) {
        return ok("Hello, " + name + "!");
    }
    // 返回 JSON 数据 (现代 API 的标准做法)
    public Result getItem(Long id) {
        // 在真实应用中,这里会从数据库查询数据
        if (id == 123) {
            return ok("{\"id\": 123, \"name\": \"Sample Item\"}");
        } else {
            return notFound("Item not found");
        }
    }
    // 异步方法,返回 CompletionStage<Result>
    // 这对于调用外部服务或数据库等耗时操作至关重要
    public CompletionStage<Result> asyncGetItem(Long id) {
        return CompletableFuture.supplyAsync(() -> {
            // 模拟一个耗时操作
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "{\"id\": " + id + ", \"name\": \"Async Item\"}";
        }).thenApply(itemJson -> ok(itemJson));
    }
}
  • Result.ok(): 返回一个 200 OK 响应。
  • Result.notFound(): 返回一个 404 Not Found 响应。
  • CompletionStage<Result>: 这是实现非阻塞异步的关键,Play 的底层是异步的,让你的控制器方法返回 CompletionStage 可以充分利用这一点。

视图

视图用于生成 HTML 响应,Play 使用自己的模板引擎,它强大且易于使用。

示例 (app/views/index.scala.html):

@(name: String) @* 定义模板接收一个名为 name 的参数 *@
<!DOCTYPE html>
<html>
    <head>
        <title>Play Framework</title>
    </head>
    <body>
        <h1>Hello @name!</h1> @* 使用 @ 符号来嵌入变量或执行代码 *@
        <p>This is a rendered view from Play.</p>
    </body>
</html>

修改控制器以使用视图:

public Result index(Http.Request request) {
    return ok(views.html.renderedPage.render("World")); // 调用视图并传入参数
}

视图文件 (`app/views/renderedPage.scala

分享:
扫描分享到社交APP
上一篇
下一篇