您的位置:首页 > 理论基础 > 计算机网络

Play Framework Web开发教程(22): Controllers–HTTP和Scala

2015-01-30 11:50 141 查看

http://www.tuicool.com/articles/eQvEbe

Play Framework Web开发教程(22): Controllers–HTTP和Scala之间的接口

时间 2014-08-27 21:30:57 引路蜂移动软件原文 http://www.imobilebbs.com/wordpress/archives/5357

Play中的控制器(Controller)是用来处理HTTP请求(以URL标识的资源),例如在一个Play应用中我们可以定义如下一些URL:
/products
/product/5010255079763
/product/5010255079763/edit

使用Play应用的路由配置,我们可以把这些URL映射到某个Controller的方法,一个URL对应一个方法。
Controller类和Action方法
根据前面定义的URL,我们可以先开始定义一个Products控制类,它将包含四个Action方法分别来处理不同的请求:list, details, edit和update,如下图:



比如其中的list方法,用来处理/products HTTP请求,返回一个产品列表等。
一个控制类在Play应用中,是一个派生于play.api.mvc.Controller类的对象,这个类提供了很多帮助编写Action方法的函数,尽管小的应用可能只需要使用一个Controller,当大多数情况使用多个Controller,每个Controller包含多个相关的Action方法。
一个Action为Controller中定义的一个方法,它返回一个类型为play.api.mvc.Action的对象,你可以使用如下方法来定义一个Action方法:
def list = Action { request =>  NotImplemented}

这定义了一个由Request => Result 的函数,用来处理一个HTTP请求并返回HTTP响应。这里NotImplemented为预定义的一个函数,它返回一个501 HTTP响应表明该方法尚未实现。Action方法也可以使用参数,它传入解析后的HTTP请求中的参数。比如,如果你需要实现分页,你使用了一个pageNumber作为参数:
def list(pageNumber: Int) = Action {  NotImplemented}

通常Action函数体中根据请求,读取或者跟新数据模型(Data Model),然后显示页面。 下面列出了我们之前需要定义的几个函数的框架:
package controllers
import play.api.mvc.{Action, Controller}
object Products extends Controller {  def list(pageNumber: Int) = Action {    NotImplemented  }  def details(ean: Long) = Action {    NotImplemented  }  def edit(ean: Long) = Action {    NotImplemented  }  def update(ean: Long) = Action {    NotImplemented  }
}

这四个Action方法,对应到下面三个URL
/products
/product/5010255079763
/product/5010255079763/edit

没有第四个URL,这是因为其中update的URL也是有第二个URL,但它使用HTTP PUT方法,而不是使用GET方法,(有兴趣的可以参考REST设计),我们可以使用不同的HTTP方法对同一个URL标识的资源进行不同的操作。通常Web 浏览器可能只支持 GET和POST方法,如果你需要使用PUT 和 DELETE方法 的请求,你需要使用不同的客户端,比如使用Javascript代码。
注:按照惯例,我们通常使用复数名词作为Controller的类名称,比如之前的Products,而定义DataModel时,可能使用其单数形式比如Product。
Play应用中,通常使用Object来定义一个Controller对象,这是因为Controller不保存任何状态,它的作用是将多个Action分组,这也是你能看到的无状态的MVC模型的一个方面。因此在一个Controller对象中不要使用var来定义成员,它的成员只可以使用val来定义。
HTTP以及Controller层面上的部分Scala API
Play应用将controllers, actions, request,和 response作为 trait来定义,它们都定义在play.api.mvc 包中。
注意:只引入play.api 包 ,play.mvc中定义的类和Scala Play应用无关(Java Play相关类)
下面一些trait和类封装了HTTP相关的一个概念,比如请求,响应和cookie

play.api.mvc.Cookie—HTTP cookie: 保存在客户端少量数据,可以作为请求的一部分。

play.api.mvc.Request—HTTP 请求: HTTP 方法, URL, headers, body,以及 cookies

play.api.mvc.RequestHeader—Request 元数据: 一个 name-value 对

play.api.mvc.Response—一个HTTP 响应, with headers and a body;

play.api.mvc.ResponseHeader—Response 元数据: a name-value 对

Controller API也定义自己的一些概念,比如Call,其它一些代表了额外的控制器功能,比如Flash,下面列出一些相关的类或trait:

play.api.mvc.Action— 一个函数,处理来自客户端的请求然后返回结果

play.api.mvc.Call— 一个HTTP 请求: 包含一个HTTP方法和URL

play.api.mvc.Content—一个HTTP 响应 ,包含content type和消息体

play.api.mvc.Controller—Controller 对象的基类

play.api.mvc.Flash— 一个临时数据存储,只对下一个请求有效,其它功能类似于Session。

play.api.mvc.Result— Action处理请求之后的返回值类型

play.api.mvc.Session—一组键-值, 保存在Cookie中

组合使用Action
有些时候,在多个Action方法中可能需要一些公用的函数,这可能会导致重复代码,比如访问控制,或者缓存一个返回结果以提高响应速度。一个常用的方法,是就这些公用的代码抽取出来定义成函数,比如:
def list = Action {// Check authentication.// Check for a cached result.// Process request...// Update cache.
}

但使用Scala我们有更好的方法,这意味着我们可以将多个Action方法组合起来使用,比如:
def list =  Authenticated {    Cached {      Action {        // Process request...      }  }
}

这个例子,我们使用Action创建了一个函数,然后又传给Cached,紧接着又传给Authenticated.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: