Play框架路由与视图开发全解析
立即解锁
发布时间: 2025-08-19 00:52:13 阅读量: 1 订阅数: 2 


精通Play框架:构建可扩展的Scala应用
### Play 框架路由与视图开发全解析
#### 1. 路由构建
在应用开发中,路由起着至关重要的作用,它能将 HTTP 请求映射到相应的控制器动作。下面我们来详细了解路由构建的相关内容。
##### 1.1 路径模式定义
在 Scala 代码中,我们可以定义路径模式,例如:
```scala
case class StaticPart(value: String) extends PathPart {
override def toString = """StaticPart("""" + value + """")"""
}
case class PathPattern(parts: Seq[PathPart]) {
def has(key: String): Boolean = parts.exists {
case DynamicPart(name, _, _) if name == key => true
case _ => false
}
override def toString = parts.map {
case DynamicPart(name, constraint, encode) => "$" + name + "<" + constraint + ">"
case StaticPart(path) => path
}.mkString
}
```
这里定义了 `StaticPart` 表示静态路径部分,`PathPattern` 用于表示整个路径模式,并且提供了 `has` 方法来检查路径模式中是否包含特定的动态部分。
##### 1.2 请求参数配置
很多应用会在 RESTful HTTP GET 请求中使用额外的参数来获取所需信息,Play 框架支持对这些请求参数进行配置。
- **基本参数配置**:假设我们要通过用户姓名搜索用户,可以这样定义路由:
```
GET /api/search/user controllers.UserController.search(name)
```
这样,我们就无需在动作中从请求里获取参数,Play 会自动处理从请求中获取参数并传递给动作。
- **可选参数配置**:当请求参数是可选的情况,比如搜索用户时 `lastName` 是可选的,我们可以指定参数类型为 `Option`:
```
GET /api/search/user controllers.UserController.search(firstName:String, lastName:Option[String])
```
- **默认值设置**:我们还可以为请求参数指定默认值。例如,为搜索请求设置 `limit` 参数的默认值为 10:
```
GET /api/search/user controllers.UserController.search(firstName:String, lastName:Option[String], limit:Int ?= 10)
```
##### 1.3 路由问题排查
当应用正常运行,但将代码添加到一个或多个基础包后,反向路由无法正常工作时,由于路由是经过编译的,所以当对控制器进行修改后,需要重新编译项目。具体操作步骤如下:
1. 运行 `clean` 命令清理项目。
2. 重新编译项目。
3. 检查生成的路由文件是否反映了所做的更改。
4. 如果没有反映更改,删除 `target` 目录并重新编译项目。
#### 2. 视图探索
视图是应用的重要组成部分,它能展示应用的功能,良好的视图可以增加终端用户数量,而复杂的视图则可能会让用户望而却步,因此视图的质量对应用的成功起着决定性作用。下面我们将介绍视图开发的相关内容。
##### 2.1 Scala 模板深入探究
Twirl 模板由参数和内容组成。以 `login.scala.html` 登录页面模板为例:
```scala
@(title: String)(content: play.twirl.api.Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
</head>
<body>
@content
</body>
</html>
```
模板参数必须首先声明,因为它们会作为生成模板对象的 `apply` 方法的参数。例如,对于上述模板,`apply` 方法如下:
```scala
def apply/*1.2*/(title: String)(content:play.api.twirl.Html) :play.api.templates.HtmlFormat.Appendable = {...}
```
模板内容可以是 HTML 也可以是 Scala 代码。Play 框架自带了一些默认页面模板,如 `todo.scala.html` 和 `unauthorized.scala.html` 都是静态页面。而 `devNotFound.scala.html` 则会根据路由情况列出所有尝试过的路由:
```scala
@(request:play.api.mvc.RequestHeader, router:Option[play.core.Router.Routes])
<!DOCTYPE html>
<html>
<head>
<title>Action not found</title>
<link rel="shortcut icon" href="data:image/png;base64,iVBORw..">
</head>
<body>
<h1>Action not found</h1>
<p id="detail">
For request '@request'
</p>
@router match {
case Some(routes) => {
<h2>
These routes have been tried, in this order:
</h2>
<div>
@routes.documentation.zipWithIndex.map { r =>
<pre><span class="line">@(r._2 + 1)</span><span class="route"><span class="verb">@r._1._1</span><span class="path">@r._1._2</span><span class="call">@r._1._3</span></span></pre>
}
</div>
}
case None => {
<h2>
No router defined.
</h2>
}
}
</body>
</html>
```
在模板中,我们可以调用模板参数类型所定义的方法,例如,如果 `books: Seq[String]` 是参数之一,我们可以在模板中调用 `@books.length` 或 `@books.map{...}` 等方法。此外,Twirl 模板还可以在另一个模板中使用,实现视图的复用。例如,定义一个主模板 `main.scala.html`:
```scala
@(title: String)(content: play.twirl.api.Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
</head>
<body>
<header>brand name</header>
@content
<footer>Copyright 2013</footer>
</body>
</html>
```
复用该模板的方式如下:
```scala
@main("locate us"){
<div>
company address
</div>
}
```
##### 2.2 视图构建示例
我们来构建一个常见的视图,让用户选择要登录的账户,默认选中第一个提供商。假设 `otherAuth` 是支持的第三方认证列表,类型为 `Seq[ThirdPartyAuth]`:
```scala
<div>
<p>
Please select the account you wish to use
@for(auth <- otherAuth) {
<input type="radio" name="account" value="@auth.id"> @auth.name
<br/>
}
</p>
</div>
```
为了设置默认值,我们使用 Twirl 提供的 `defining` 方法:
```scala
<div>
<p>
Please select the account you wish to use
@for(auth <- otherAuth) {
@defining(auth.id == otherAuth.head.id) { isChecked =>
@if(isChecked) {
<input type="radio" name="account" value="@auth.id" checked="checked"> @auth.name
} else {
<input type="radio" name="account" value="@auth.id"> @auth.name
```
0
0
复制全文
相关推荐










