baeldung 2024-01-08
1. 概述
本入门教程旨在探索 Play 框架,并了解如何使用它创建 Web 应用程序。
Play 是一个面向 JVM(Java 虚拟机)上编译和运行的编程语言(主要是 Java 和 Scala)的高生产力 Web 应用框架。它集成了现代 Web 应用开发所需的各种组件和 API。
2. Play 框架环境搭建
首先,前往 Play 框架的官方网站,下载最新版本的分发包。撰写本文时,最新版本为 2.7。
我们将下载 Play Java Hello World 教程 的 zip 文件,并将其解压到一个方便的位置。在该文件夹的根目录下,我们会找到一个名为 sbt 的可执行文件,可用于运行应用程序。或者,也可以从 sbt 官方网站 安装 sbt。
如果使用下载包中的 sbt 脚本,请执行以下命令:
cd /path/to/folder/
./sbt run
注意:这里我们运行的是当前目录下的脚本,因此使用了 ./ 前缀。
如果你已经全局安装了 sbt,则可以这样运行:
cd /path/to/folder/
sbt run
执行上述命令后,你会看到类似 “(Server started, use Enter to stop and go back to the console…)” 的提示信息。这意味着应用已成功启动,现在可以访问 http://localhost:9000,你会看到 Play 的欢迎页面:
3. Play 应用程序结构剖析
在本节中,我们将深入了解 Play 应用的目录结构,以及每个文件和目录的作用。
如果你想立即动手尝试一个简单示例,也可以直接跳到下一节。
典型的 Play 框架应用程序包含以下文件和目录结构:
├── app → 应用源代码
│ ├── assets → 编译型资源源文件(如 CoffeeScript、LESS)
│ │ ├── javascripts → 通常是 CoffeeScript 源文件
│ │ └── stylesheets → 通常是 LESS CSS 源文件
│ ├── controllers → 应用控制器
│ ├── models → 应用业务逻辑层
│ └── views → 模板文件
├── build.sbt → 应用构建脚本
├── conf → 配置文件及其他非编译资源(位于 classpath 中)
│ ├── application.conf → 主配置文件
│ └── routes → 路由定义
├── dist → 打包时需包含的任意文件
├── lib → 未托管的第三方库依赖(JAR 文件)
├── logs → 日志目录
│ └── application.log → 默认日志文件
├── project → sbt 构建配置文件
│ ├── build.properties → sbt 项目标记文件
│ └── plugins.sbt → sbt 插件声明(包括 Play 自身)
├── public → 公共静态资源
│ ├── images → 图片文件
│ ├── javascripts → JavaScript 文件
│ └── stylesheets → CSS 文件
├── target → 构建系统生成的文件
│ ├── resolution-cache → 依赖信息
│ ├── scala-2.11
│ │ ├── api → 生成的 API 文档
│ │ ├── classes → 编译后的 class 文件
│ │ ├── routes → 由 routes 文件生成的源码
│ │ └── twirl → 由模板生成的源码
│ ├── universal → 应用打包输出
│ └── web → 编译后的 Web 资源
└── test → 单元测试或功能测试源码目录
3.1 app 目录
该目录包含 Java 源代码、Web 模板和编译型资源源文件——基本上是所有可执行资源。
它包含几个重要的子目录,分别对应 MVC 架构模式的各个部分:
- models:应用的业务逻辑层。这些类通常用于映射数据库表,并提供对持久化层的访问。
- views:包含所有可渲染到浏览器的 HTML 模板。
- controllers:存放控制器的 Java 源文件。控制器中的公共方法称为“动作(Action)”,用于处理 HTTP 请求并返回 HTTP 响应。
- assets:存放需编译的前端资源,如 CSS 和 JavaScript。
注意:上述命名约定是灵活的。你可以创建自己的包,例如
app/utils,也可以自定义包路径,如app/com/msm/controllers。
3.2 public 目录
public 目录中的资源是静态资产,由 Web 服务器直接提供服务。
通常包含三个子目录:images、javascripts 和 stylesheets。建议按此结构组织静态资源,以保持 Play 应用的一致性。
3.3 conf 目录
该目录包含应用的配置文件:
application.conf:主配置文件,用于设置 Play 应用的各项参数。routes:定义 URL 路由规则,将请求映射到对应的控制器动作。
如有其他配置需求,也应将相关文件放在此目录下。
3.4 lib 目录
这是一个可选目录,用于存放未通过构建工具管理的 JAR 依赖。放入此目录的 JAR 文件会自动加入应用的 classpath。
3.5 build.sbt 文件
这是应用的构建脚本,用于声明项目依赖(如测试库、持久化库等)。
3.6 project 目录
包含所有基于 SBT 的构建配置文件,例如:
build.properties:标识 sbt 项目版本。plugins.sbt:声明 sbt 插件,包括 Play 框架本身。
3.7 target 目录
由构建系统自动生成的文件都存放在此目录,例如 .class 文件、生成的路由代码、模板编译结果等。
在了解了 Play Hello World 示例的目录结构后,我们可以通过一个简单示例来深入理解框架的基本原理。
4. 简单示例
本节将创建一个非常基础的 Web 应用,帮助我们熟悉 Play 框架的核心概念。
这次我们不使用下载的示例项目,而是通过 sbt new 命令创建新项目。
打开命令行,进入你希望创建项目的目录,执行以下命令:
sbt new playframework/play-java-seed.g8
注意:此操作要求你已按第 2 节所述安装了 sbt。
执行后,sbt 会提示你输入项目名称和 Java 包名(采用反向域名格式,如 com.example)。若直接按回车,则使用方括号中显示的默认值。
生成的项目结构与之前下载的 Hello World 示例一致。我们可以像之前一样运行它:
cd /path/to/folder/
sbt run
构建完成后,服务器将在 9000 端口启动,访问 http://localhost:9000 即可看到 “Welcome to Play” 消息。
该应用目前有两个端点:
- 根路径
/:显示欢迎页面。 /assets:用于提供静态资源。例如,访问 http://localhost:9000/assets/images/favicon.png 可下载 favicon 图标。
5. 动作(Actions)与控制器(Controllers)
在 Play 中,动作(Action) 是控制器类中的一个 Java 方法,用于处理请求参数并向客户端返回响应结果。
控制器(Controller) 是一个继承自 play.mvc.Controller 的 Java 类,用于将相关的动作逻辑组织在一起。
让我们查看 app/controllers/HomeController.java 文件:
public Result index() {
return ok(views.html.index.render());
}
该 index 动作返回一个由 views.html.index 模板渲染的网页。
模板内容如下(位于 app/views/index.scala.html):
@main("Welcome to Play") {
<h1>Welcome to Play!</h1>
}
该模板调用了 main 布局模板。main 模板负责渲染 HTML 的 <head> 和 <body> 结构,接收两个参数:
title: String:页面标题content: Html:页面主体内容
main.scala.html 内容如下:
@(title: String)(content: Html)
<!DOCTYPE html>
<html lang="en">
<head>
<title>@title</title>
<link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
</head>
<body>
@content
<script src="@routes.Assets.versioned("javascripts/main.js")" type="text/javascript"></script>
</body>
</html>
现在,我们修改 index.scala.html 中的内容:
@main("Welcome to Mianshima") {
<h1>Welcome to Play Framework Tutorial on Mianshima!</h1>
}
刷新浏览器后,页面将显示:
Welcome to Play Framework Tutorial on Mianshima!
你也可以完全绕过模板,直接在控制器中返回纯文本或 HTML:
public Result index() {
return ok("REST API with Play by Mianshima");
}
此时浏览器将仅显示纯文本(无任何 HTML 样式):
REST API with Play by Mianshima
或者,返回 HTML 内容:
public Result applyHtml() {
return ok(Html.apply("<h1>This text will appear as a heading 1</h1>"));
}
并在 conf/routes 中添加路由:
GET /msm/html controllers.HomeController.applyHtml
访问 http://localhost:9000/msm/html 即可看到格式化的 HTML 标题。
关键特性说明:
- 热重载(Hot Reload):Play 会在代码修改后自动重新编译,刷新浏览器即可看到最新效果。
- HTTP 响应辅助方法:
play.mvc.Results类提供了多种便捷方法,如:
ok()→ HTTP 200notFound()→ HTTP 404badRequest()→ HTTP 400
6. 响应结果的定制
Play 支持内容协商(Content Negotiation),能根据响应体自动推断 Content-Type。例如:
return ok("text to display");
Play 会自动设置 Content-Type: text/plain。
但你也可以手动指定内容类型:
public Result customContentType() {
return ok("This is some text content").as("text/html");
}
同样适用于其他类型,如 text/plain、application/json 等。
还可以添加自定义响应头:
public Result setHeaders() {
return ok("This is some text content")
.as("text/html")
.withHeader("Header-Key", "Some value");
}
7. 结论
本文介绍了 Play 框架的基础知识,并演示了如何使用 Play 创建一个简单的 Java Web 应用程序。通过控制器、动作、模板和路由的配合,我们可以快速构建现代化的 Web 服务。Play 的热重载、简洁的 API 和强大的内容协商机制,使其成为高效开发 Web 应用的理想选择。