体验 Scala 语言的 Play Web 框架

简介: 体验 Scala 语言的 Play Web 框架

1. 概览

在本文中将介绍 Scala 的 Play Web 开发框架。我们将会学习如何创建一个 Play 项目,使用开发工具生成我们的第一个项目以及实现自定义的功能,另外还将体验一下 Play 框架的测试能力。

对于 Java 开发者来说,也可以看这篇文章 Introduction To Play In Java

2. 项目搭建

在开始之前,我们需要安装 sbt 命令行工具 (至少是 JDK 8 及以上),在本文中我们将使用 sbt 1.6.2 来安装 Play Framework 2.8.16

3. 命令行工具

Play 框架官方文档提到 sbt 是一个强大的控制台和构建工具,我们可以从使用 sbt 工具生成一个空白的 Play 框架的项目开始。

sbt new playframework/play-scala-seed.g8
复制代码

f326aa302c60450493649df05df91650_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

在依赖信息加载完成后,该工具将提示并要求我们输入新项目的名称和组织信息

This template generates a Play Scala project 
name [play-scala-seed]:
复制代码

我们给这个项目命名为 baeldung-play-framework.。组织的名称将会作为项目中包的名称,Scala 的包名的命名规则和 Java 的包名命名规则一样,因此我可以可以给包命名为 baeldung.com

2839ee8dc56c46569659e5229f84a926_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

现在,我们可以进入到 baeldung-play-framework 项目文件夹中并启动该项目

cd baeldung-play-framework 
sbt run
复制代码

这是我们第一次启动项目,可能会花点时间在构建和编译上。

d98dde81a71748b79fb12fa17d797eab_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

178411950cd24ce88aa032fa1430a7cd_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

92ac5f5327544083b45f98af47505090_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

完成后我们可以通过浏览器进入 http://localhost:9000/ 就可以看到默认的欢迎页面了

ddde467cfc0b44a0a603aef17743717d_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

到目前为止我们已经通过 Play 框架创建了一个正在运行的 HTTP 服务器,并且没有书写一行代码就完成了。

4. 项目结构

现在,可以使用 IntelliJ IDE 打开项目并查看项目的目录结构

b9cf14c5530e4a8897f15c346b4f5808_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

在项目目录中,有四个文件夹是由 sbt 模板创建的,分别是 app/controllers, app/views, confpublic

  • controllers 目录用来保存 Scala 代码
  • views 目录用来保存 HTML 模板
  • conf 保存着路由配置既请求的 URL 地址和类以及函数的映射关系
  • public 目录保存着 Play 框架服务器的一些静态内容
baedung-play-framework$ tree -L 2
.
├── app
│   ├── controllers
│   └── views
├── build.sbt
├── build.sc
├── conf
│   ├── application.conf
│   ├── logback.xml
│   ├── messages
│   └── routes
├── logs
│   └── application.log
├── project
│   ├── build.properties
│   ├── plugins.sbt
│   ├── project
│   └── target
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
├── target
│   ├── global-logging
│   ├── scala-2.13
│   ├── streams
│   ├── task-temp-directory
│   └── web
└── test
    └── controllers
20 directories, 9 files
复制代码

这就是目前我们需要了解的关于项目的目录结构。

5. 第一次变更

Play 框架为我们提供了一个“点击刷新工作流”。意味着我们可以通过刷新浏览器就可以查看更改后的内容,而无需重新启动服务器。

首先我们在 app/views 文件夹下创建一个新文件并命名为 firstexample.scala.html

7b318f447a3c4adb9abe26fd1a2eb2d1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

打开这个文件并输入以下代码:

@()
@main("Welcome to Introductio to Play Framework"){
  <h1>Welcome to Introduction to Play Framework</h1>
}
复制代码

除了修改 HTML 文件,我们还必须修改 Scala 代码。打开 app/controllers/HomeController.scalas 文件并将:Ok(views.html.index()) 更改为 Ok(viewers.html.firstexample())

def index() = Action { implicit request: Request[AnyContent] =>
  Ok(views.html.index())
}
复制代码
def index() = Action { implicit request: Request[AnyContent] =>
  Ok(views.html.firstexample())
}
复制代码

查看仍在运行的 Play 服务器的输出时,没有看到任何新内容。似乎更改未生效。

但是,当我们点击浏览器中的 “刷新” 按钮时,我们将在浏览器窗口中看到以下内容:

image.png

6. 如何定义一个新的请求

在前面的示例中,我们对代码进行了一些更改,并看到了更改后的结果。现在,让我们看看 Play 框架项目的内部结构,了解它是如何工作的,以及我们还可以做什么。

当 Play 项目服务器接收到请求时,它首先会检查 conf/routes 文件,以确定哪个 Controller 控制器和方法将处理该请求。在 Controller 控制器内部定义并在路由文件中使用的方法称为 Action。

我们想在 HomeController 控制器中定义一个新的 Action 以及路由,这个 Action 将会从 URL 地址中接收到两个参数并且打印出这两个数的和。简单来说我们将从 URL 中读取两个数并且在页面中展示这两个数的和

为了实现这个功能,我们需要在 HomeController.scala 控制器中添加新的方法,这个方法接收两个参数,计算它们的和并传递到视图模板中渲染。

def printSum(first: Long, second: Long) = Action { implicit  request: Request[AnyContent] =>
  val sum = first + second
  Ok(views.html.index(sum))
}
复制代码

image.png

现在打开视图模板 index.scala.html,在模板顶部添加 sum 参数并在内容中使用这个参数

@(sum: Long)
@main("Add two numbers") {
  <h1>The sum is @sum</h1>
}
复制代码

image.png

我们刚刚定义了一个生成页面的函数。视图文件的第一行描述函数参数。其他行是生成输出的代码。

sum 参数在 HomeController.scala 中计算并传递给 Ok 函数,该函数返回状态代码为 200 内容为 OK

最后我们需要打开 conf/routes 文件并添加一个新的路径和 action

# add two numbers
GET /sum/:first/:second controllers.HomeController.printSum(first: Long, second: Long)
复制代码

image.png

该路由包含了三个部分,第一个是 HTTP 的请求方式,接着我们定义了路径以及参数,这里我们使用两个变量 first 和 second 来计算 sum 参数。

最后我们通过指定 Controller 以及处理请求的 action,需要注意的是我们在路径中使用的参数正是函数中用到的参数。

在浏览器中打开如下地址 http://localhost:9000/sum/5/15 就可以看到这个页面

image.png

7. 编写测试用例

最后,我们来看看有 sbt 命令行工具在创建 Play 框架项目的时候生成的测试用例文件夹。

tests/controllers 目录下打开 HomeControllerSpec 文件时,我们会看到 ScalaTest 的一些规范。

image.png

为了使测试用例更完整,我们需要为我们路由编写测试用例。定义一个名为 “render a page that prints the sum of two numbers” 的新测试用例,该测试用例会调用 /sum 路由并带有两个路径参数

"render a page that prints the sum of two numbers" in {
  val request = FakeRequest(GET, "/sum/10/20")
  val sumOfNumbers = route(app, request).get
}
复制代码

调用完之后还需要添加断言来判断结果,在这个测试用例中我们期望看到 “The sum is 30” 在 HTML 页面上渲染出来。

// 断言内容
status(sumOfNumbers) mustBe OK
contentType(sumOfNumbers) mustBe Some("text/html")
contentAsString(sumOfNumbers) must include("The sum is 30")
复制代码

image.png

我们可以通过 sb test 命令来执行测试,执行完成后就可以看到我们的测试用执行通过

image.png

image.png

8. 总结

在本文中,我们使用 Play Framework 的命令行工具创建了一个简单的网站,添加了一个新的视图模板,并使用参数化模板定义了一条新路由。最后,我们查看了自动生成的测试用例并实现了我们创建的功能的测试用例并通过测试。

该项目的源码可以在 GitHub 上获得。


相关文章
|
10天前
|
缓存 监控 测试技术
【Go语言专栏】使用Go语言构建高性能Web服务
【4月更文挑战第30天】本文探讨了使用Go语言构建高性能Web服务的策略,包括Go语言在并发处理和内存管理上的优势、基本原则(如保持简单、缓存和并发控制)、标准库与第三方框架的选择、编写高效的HTTP处理器、数据库优化以及性能测试和监控。通过遵循最佳实践,开发者可以充分利用Go语言的特性,构建出高性能的Web服务。
|
10天前
|
中间件 Go API
【Go 语言专栏】Go 语言中的 Web 框架比较与选择
【4月更文挑战第30天】本文对比了Go语言中的四个常见Web框架:功能全面的Beego、轻量级高性能的Gin、简洁高效的Echo,以及各自的性能、功能特性、社区支持。选择框架时需考虑项目需求、性能要求、团队经验和社区生态。开发者应根据具体情况进行权衡,以找到最适合的框架。
|
11天前
|
机器学习/深度学习 前端开发 数据可视化
数据分析web可视化神器---streamlit框架,无需懂前端也能搭建出精美的web网站页面
数据分析web可视化神器---streamlit框架,无需懂前端也能搭建出精美的web网站页面
|
11天前
|
开发框架 前端开发 JavaScript
学会Web UI框架--Bootstrap,快速搭建出漂亮的前端界面
学会Web UI框架--Bootstrap,快速搭建出漂亮的前端界面
|
11天前
|
缓存 前端开发 安全
Python web框架fastapi中间件的使用,CORS跨域详解
Python web框架fastapi中间件的使用,CORS跨域详解
|
11天前
|
API 数据库 Python
Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法
Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法
|
11天前
|
关系型数据库 MySQL API
Python web框架fastapi数据库操作ORM(一)
Python web框架fastapi数据库操作ORM(一)
|
11天前
|
Python
python web框架fastapi模板渲染--Jinja2使用技巧总结
python web框架fastapi模板渲染--Jinja2使用技巧总结
|
11天前
|
开发框架 网络协议 前端开发
Python高性能web框架--Fastapi快速入门
Python高性能web框架--Fastapi快速入门
|
11天前
|
网络协议 数据库 开发者
构建高效Python Web应用:异步编程与Tornado框架
【4月更文挑战第29天】在Web开发领域,响应时间和并发处理能力是衡量应用性能的关键指标。Python作为一种广泛使用的编程语言,其异步编程特性为创建高性能Web服务提供了可能。本文将深入探讨Python中的异步编程概念,并介绍Tornado框架如何利用这一机制来提升Web应用的性能。通过实例分析,我们将了解如何在实际应用中实现高效的请求处理和I/O操作,以及如何优化数据库查询,以支持更高的并发用户数和更快的响应时间。