Scala下Play框架学习笔记(Http Routing)

内置的HTTP路由

路由把每一个引进来的HTTP请求对应到相应的Action去。

HTTP请求被认为是MVC框架下的一个事件,这一事件包含两部分主要信息:

(1)请求路径,包括query String

(2)HTTP方法,如get,post等

   路由被定义在经过编译的conf/routes中,因此你能在浏览器上直接看到报错信息。

Scala下Play框架学习笔记(Http Routing)

conf/routes中每一行一般由HTTP方法和相应URI组成:

GET   /clients/:id          controllers.Clients.show(id: Long)

也可加上评论:

# Display a client.

GET   /clients/:id          controllers.Clients.show(id: Long)

以下这个不太懂,请高人指教:

->      /api                        api.MyRouter

HTTP方法

HTTP方法包括get、post、patch、put、delete、head等。

URI PATTERN

URI PATTERN定义了routes的路径,部分请求路径可以是动态的。

(1)静态路径:

准确匹配请求路径,可以定义如下:

GET   /clients/all          controllers.Clients.list()

 (2)动态的部分:

如果要通过ID来搜索路径,需要用动态指定的方式。

GET   /clients/:id          controllers.Clients.show(id: Long)

The default matching strategy for a dynamic part is defined by the regular expression [^/]+, meaning that any dynamic part defined as :id will match exactly one URI path segment.

通过*id可以来匹配多个URI,如下:

GET   /files/*name          controllers.Application.download(name)

以上的router,对于GET /files/p_w_picpaths/logo.png这样的请求,name会匹配p_w_picpaths/logo.png。

用自定义正则表达式动态路由

$id<regex>可以来自定义正则表达式

GET   /items/$id<[0-9]+>    controllers.Items.show(id: Long)

 the parameter is not decoded by the router or encoded by the reverse router. You’re responsible for validating the input to make sure it makes sense in that context.

controller action method

如果方法没有参数,可以如下定义:

GET   /                     controllers.Application.homePage()

如果有参数,则从请求URI中寻找参数:

# Extract the page parameter from the path.

GET   /:page                controllers.Application.show(page)

或者如下:

# Extract the page parameter from the query string.

GET   /                     controllers.Application.show(page)

show方法的定义如下:

def show(page: String) = Action {
  loadContentFromDatabase(page).map { htmlContent =>
    Ok(htmlContent).as("text/html")
  }.getOrElse(NotFound)

}

如果要把入参转换成scala的数据类型,就要有下面的router,并且实现相应的方法:

GET   /clients/:id          controllers.Clients.show(id: Long)

def show(id: Long) = Action {
  Client.findById(id).map { client =>
    Ok(views.html.Clients.display(client))
  }.getOrElse(NotFound)

}

固定值的参数:

# Extract the page parameter from the path, or fix the value for /
GET   /                     controllers.Application.show(page = "home")

GET   /:page                controllers.Application.show(page)

默认值方式:

# Pagination links, like /clients?page=3

GET   /clients              controllers.Clients.list(page: Int ?= 1)

Option类型,不需要在每一次传参时都传入:

# The version parameter is optional. E.g. /api/list-all?version=3.0

GET   /api/list-all         controllers.Api.list(version: Option[String])

注:多个routes冲突时,使用第一个。

play.api.mvc.Call中提供了HTTP回调,提供了HTTP和URI方法,它用如下方法创建控制器:

package controllers

import play.api._
import play.api.mvc._

class Application extends Controller {

 
def hello(name: String) = Action {
   
Ok("Hello " + name + "!")
 
}

}

如果在conf/routes中有如下定义:

# Hello action
GET   
/hello/:name          controllers.Application.hello(name)

那么可以通过controllers.routes.Application实现控制反转:

// Redirect to /hello/Bob
def helloBob = Action {
 
Redirect(routes.Application.hello("Bob"))

}

默认控制器:

# Redirects to https://www.playframework.com/ with 303 See Other
GET   
/about      controllers.Default.redirect(to = "https://www.playframework.com/")

# Responds with 404 Not Found
GET   
/orders     controllers.Default.notFound

# Responds with 500 Internal Server Error
GET   
/clients    controllers.Default.error

# Responds with 501 Not Implemented
GET   
/posts      controllers.Default.todo