- 浏览: 2567503 次
- 性别:
- 来自: 成都
-
文章分类
最新评论
-
nation:
你好,在部署Mesos+Spark的运行环境时,出现一个现象, ...
Spark(4)Deal with Mesos -
sillycat:
AMAZON Relatedhttps://www.godad ...
AMAZON API Gateway(2)Client Side SSL with NGINX -
sillycat:
sudo usermod -aG docker ec2-use ...
Docker and VirtualBox(1)Set up Shared Disk for Virtual Box -
sillycat:
Every Half an Hour30 * * * * /u ...
Build Home NAS(3)Data Redundancy -
sillycat:
3 List the Cron Job I Have>c ...
Build Home NAS(3)Data Redundancy
Playframework(7)Scala Project and HTTP Programming
1. HTTP Programming
1.1 Actions, Controllers and Results
play.api.mvc.Result function that handles a request and generates a result to be sent to the client.
val echo = Action{ requets =>
Ok("Got request [" + request + "]")
}
Building an Action
Action {
Ok("Hello World")
}
That is the simple action, but we can not get a reference to the incoming request.
So there is another Action Builder that takes as an argument a function
Action { request =>
Ok("Got request [ " + request + "]")
}
Action(parse.json) { implicit request =>
Ok("Got request [ " + request + "]")
}
We specify an additional BodyParser argument.
Controllers are action generators
A Controller is nothing more than a singleton object that generates Action values.
object Application extends Controller {
def index = Action {
Ok("It works!")
}
}
Of course, the action generator method can have parameters, and these parameters can be captured b the Action closure:
def hello(name: String) = Action {
Ok("Hello " + name)
}
Simple Results
An HTTP result with a status code, a set of HTTP headers and a body to be sent to the web client. These results are defined by play.api.mvc.SimpleResult
def index = Action {
SimpleResult(
header = ResponseHeader(200, Map(CONTENT_TYPE -> "text/plain")),
body = Enumerator("Hello world!");
)
}
Ok is the helper to create common results. Ok("Hello world!")
Here are several examples to create various results:
val ok = Ok("Hello world!")
val notFound = NotFound
val pageNotFound = NotFound(<h1>Page not found</h1>)
val badRequest = BadRequest(views.html.form(formWithErrors))
val oops = InternalServerError("Oops");
val anyStatus = Status(488)("Strange response type!")
Redirects are simple results too
def index = Action{
Redirect("/user/home")
}
The default is using a 303 SEE_OTHER response type.
def index = Action{
Redirect("/user/home", status = MOVED_PERMANENTLY) // permanently
}
"TODO" dummy page
def index(name: String) = TODO
1.2 HTTP routing
The built-in HTTP router
An HTTP request is seen as an event by the MVC framework. This event contains 2 major pieces of information:
the request path, including the query string (e.g. /clients/1542, /photos/list)
the HTTP method (e.g. GET, POST, …)
The routes file syntax
HTTP method URI pattern a call to an Action generator
GET /clients/:id controllers.Clients.show(id:Long)
The HTTP method
GET, POST, PUT, DELETE, HEAD
The URI pattern
Static path
GET /clients/all controllers.Clients.list()
Dynamic parts
GET /clients/:id controllers.Clients.show(id: Long)
Dynamic parts spanning several /
GET /files/*name controllers.Application.download(name)
Here for a request like GET /files/images/logo.png, the name dynamic part will capture the images/logo.png value.
Dynamic parts with custom regular expressions
GET /clients/$id<[0-9]+> controllers.Clients.show(id: Long)
Call to the action generator method
controllers.Application.show(page)
Parameter types
GET /client/:id controllers.Clients.show(id: Long)
Parameters with fixed values
GET / controllers.Application.show(page="home")
Parameters with default values
GET /clients controllers.Clients.list(page: Int ?= 1)
Routing priority
Many routes can match the same request. If there is a conflict, the first route (in declaration order) is used.
Reverse routing
GET /hello/:name controllers.Application.hello(name)
def helloBob = Action{
Redirect(routes.Application.hello("Bob"))
}
1.3 Manipulating Result
Changing the default Content-Type
val textResult = Ok("Hello World!") will automatically set the Content-Type header to text/plain, while:
val xmlResult = Ok(<message>Hello World!</message)
will set the Content-Type header to text/xml.
That will happen automatically, but sometimes, we want to control that. We can use as(newContentType) method on a result to create a new similar result with a different Content-Type header:
val htmlResult = Ok(<h1>Hello World!</h1).as("text/html")
or even better, using:
val htmlResult = Ok(<h1>Hello World!</h1>)as(HTML)
Manipulating HTTP Headers
Ok("Hello World!").withHeaders(
CACHE_CONTROL -> "max-age=3600",
ETAG -> "xx"
)
Setting and discarding cookies
Ok("Hello world").withCookies(
Cookie("theme", "blue")
)
Ok("Hello world").discardingCookies("theme")
Changing the charset for text based HTTP response
implicit val myCustomCharset = Codec.javaSupported("iso-8859-1")
1.4 Session and Flash Scopes
The same as java play, data stored in the Session are available during the whole user Session, and data stored in the Flash scope are available to the next request only.
Reading a Session value
def index = Action { request =>
request.session.get("connected").map{ user =>
Ok("Hello " + user)
}.getOrElse{
Unauthorized("Oops, you are not connected")
}
}
Alternatively you can retrieve the Session implicitly from a request:
def index = Action { implicit request =>
session.get("connected").map{ user =>
Ok("Hello " + user)
}.getOrElse{
Unauthorized("Oops, you are not connected")
}
}
Storing data in the Session
Ok("Welcome!").withSession(
"connected" -> "user@gmail.com"
)
This method will replace the whole session. If we only need to add an element to an existing Session, just add an element to the incoming session.
Ok("Hello World!").withSession(
session + ("saidHello" -> "yes" )
)
Discarding the whole session
Ok("Bye").withNewSession
Flash Scope
The flash scope works exactly like the Session, but with two differences:
data are kept for only one request
the Flash cookie is not signed, making it possible for the user to modify it.
The flash scope data are just kept for the next request and because there are no guarantees to ensure the request order in a complex Web application, the flash scope is subject to race conditions.
def index = Action { implicit request =>
Ok{
flash.get("success").getOrElse("Welcome!")
}
}
def save = Action{
Redirect("/home").flashing(
"success" -> "The item has been created"
)
}
References:
http://www.playframework.org/documentation/2.0.4/ScalaHome
http://www.playframework.org/documentation/2.0.4/ScalaActions
1. HTTP Programming
1.1 Actions, Controllers and Results
play.api.mvc.Result function that handles a request and generates a result to be sent to the client.
val echo = Action{ requets =>
Ok("Got request [" + request + "]")
}
Building an Action
Action {
Ok("Hello World")
}
That is the simple action, but we can not get a reference to the incoming request.
So there is another Action Builder that takes as an argument a function
Action { request =>
Ok("Got request [ " + request + "]")
}
Action(parse.json) { implicit request =>
Ok("Got request [ " + request + "]")
}
We specify an additional BodyParser argument.
Controllers are action generators
A Controller is nothing more than a singleton object that generates Action values.
object Application extends Controller {
def index = Action {
Ok("It works!")
}
}
Of course, the action generator method can have parameters, and these parameters can be captured b the Action closure:
def hello(name: String) = Action {
Ok("Hello " + name)
}
Simple Results
An HTTP result with a status code, a set of HTTP headers and a body to be sent to the web client. These results are defined by play.api.mvc.SimpleResult
def index = Action {
SimpleResult(
header = ResponseHeader(200, Map(CONTENT_TYPE -> "text/plain")),
body = Enumerator("Hello world!");
)
}
Ok is the helper to create common results. Ok("Hello world!")
Here are several examples to create various results:
val ok = Ok("Hello world!")
val notFound = NotFound
val pageNotFound = NotFound(<h1>Page not found</h1>)
val badRequest = BadRequest(views.html.form(formWithErrors))
val oops = InternalServerError("Oops");
val anyStatus = Status(488)("Strange response type!")
Redirects are simple results too
def index = Action{
Redirect("/user/home")
}
The default is using a 303 SEE_OTHER response type.
def index = Action{
Redirect("/user/home", status = MOVED_PERMANENTLY) // permanently
}
"TODO" dummy page
def index(name: String) = TODO
1.2 HTTP routing
The built-in HTTP router
An HTTP request is seen as an event by the MVC framework. This event contains 2 major pieces of information:
the request path, including the query string (e.g. /clients/1542, /photos/list)
the HTTP method (e.g. GET, POST, …)
The routes file syntax
HTTP method URI pattern a call to an Action generator
GET /clients/:id controllers.Clients.show(id:Long)
The HTTP method
GET, POST, PUT, DELETE, HEAD
The URI pattern
Static path
GET /clients/all controllers.Clients.list()
Dynamic parts
GET /clients/:id controllers.Clients.show(id: Long)
Dynamic parts spanning several /
GET /files/*name controllers.Application.download(name)
Here for a request like GET /files/images/logo.png, the name dynamic part will capture the images/logo.png value.
Dynamic parts with custom regular expressions
GET /clients/$id<[0-9]+> controllers.Clients.show(id: Long)
Call to the action generator method
controllers.Application.show(page)
Parameter types
GET /client/:id controllers.Clients.show(id: Long)
Parameters with fixed values
GET / controllers.Application.show(page="home")
Parameters with default values
GET /clients controllers.Clients.list(page: Int ?= 1)
Routing priority
Many routes can match the same request. If there is a conflict, the first route (in declaration order) is used.
Reverse routing
GET /hello/:name controllers.Application.hello(name)
def helloBob = Action{
Redirect(routes.Application.hello("Bob"))
}
1.3 Manipulating Result
Changing the default Content-Type
val textResult = Ok("Hello World!") will automatically set the Content-Type header to text/plain, while:
val xmlResult = Ok(<message>Hello World!</message)
will set the Content-Type header to text/xml.
That will happen automatically, but sometimes, we want to control that. We can use as(newContentType) method on a result to create a new similar result with a different Content-Type header:
val htmlResult = Ok(<h1>Hello World!</h1).as("text/html")
or even better, using:
val htmlResult = Ok(<h1>Hello World!</h1>)as(HTML)
Manipulating HTTP Headers
Ok("Hello World!").withHeaders(
CACHE_CONTROL -> "max-age=3600",
ETAG -> "xx"
)
Setting and discarding cookies
Ok("Hello world").withCookies(
Cookie("theme", "blue")
)
Ok("Hello world").discardingCookies("theme")
Changing the charset for text based HTTP response
implicit val myCustomCharset = Codec.javaSupported("iso-8859-1")
1.4 Session and Flash Scopes
The same as java play, data stored in the Session are available during the whole user Session, and data stored in the Flash scope are available to the next request only.
Reading a Session value
def index = Action { request =>
request.session.get("connected").map{ user =>
Ok("Hello " + user)
}.getOrElse{
Unauthorized("Oops, you are not connected")
}
}
Alternatively you can retrieve the Session implicitly from a request:
def index = Action { implicit request =>
session.get("connected").map{ user =>
Ok("Hello " + user)
}.getOrElse{
Unauthorized("Oops, you are not connected")
}
}
Storing data in the Session
Ok("Welcome!").withSession(
"connected" -> "user@gmail.com"
)
This method will replace the whole session. If we only need to add an element to an existing Session, just add an element to the incoming session.
Ok("Hello World!").withSession(
session + ("saidHello" -> "yes" )
)
Discarding the whole session
Ok("Bye").withNewSession
Flash Scope
The flash scope works exactly like the Session, but with two differences:
data are kept for only one request
the Flash cookie is not signed, making it possible for the user to modify it.
The flash scope data are just kept for the next request and because there are no guarantees to ensure the request order in a complex Web application, the flash scope is subject to race conditions.
def index = Action { implicit request =>
Ok{
flash.get("success").getOrElse("Welcome!")
}
}
def save = Action{
Redirect("/home").flashing(
"success" -> "The item has been created"
)
}
References:
http://www.playframework.org/documentation/2.0.4/ScalaHome
http://www.playframework.org/documentation/2.0.4/ScalaActions
发表评论
-
NodeJS12 and Zlib
2020-04-01 07:44 492NodeJS12 and Zlib It works as ... -
Traefik 2020(1)Introduction and Installation
2020-03-29 13:52 351Traefik 2020(1)Introduction and ... -
Private Registry 2020(1)No auth in registry Nginx AUTH for UI
2020-03-18 00:56 449Private Registry 2020(1)No auth ... -
Buffer in NodeJS 12 and NodeJS 8
2020-02-25 06:43 401Buffer in NodeJS 12 and NodeJS ... -
NodeJS ENV Similar to JENV and PyENV
2020-02-25 05:14 496NodeJS ENV Similar to JENV and ... -
Prometheus HA 2020(3)AlertManager Cluster
2020-02-24 01:47 438Prometheus HA 2020(3)AlertManag ... -
Serverless with NodeJS and TencentCloud 2020(5)CRON and Settings
2020-02-24 01:46 346Serverless with NodeJS and Tenc ... -
GraphQL 2019(3)Connect to MySQL
2020-02-24 01:48 262GraphQL 2019(3)Connect to MySQL ... -
GraphQL 2019(2)GraphQL and Deploy to Tencent Cloud
2020-02-24 01:48 463GraphQL 2019(2)GraphQL and Depl ... -
GraphQL 2019(1)Apollo Basic
2020-02-19 01:36 336GraphQL 2019(1)Apollo Basic Cl ... -
Serverless with NodeJS and TencentCloud 2020(4)Multiple Handlers and Running wit
2020-02-19 01:19 322Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(3)Build Tree and Traverse Tree
2020-02-19 01:19 330Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(2)Trigger SCF in SCF
2020-02-19 01:18 306Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(1)Running with Component
2020-02-19 01:17 320Serverless with NodeJS and Tenc ... -
NodeJS MySQL Library and npmjs
2020-02-07 06:21 307NodeJS MySQL Library and npmjs ... -
Python Library 2019(1)requests and aiohttp
2019-12-18 01:12 272Python Library 2019(1)requests ... -
NodeJS Installation 2019
2019-10-20 02:57 586NodeJS Installation 2019 Insta ... -
Monitor Tool 2019(2)Monit on Multiple Instances and Email Alerts
2019-10-18 10:57 279Monitor Tool 2019(2)Monit on Mu ... -
Sqlite Database 2019(1)Sqlite3 Installation and Docker phpsqliteadmin
2019-09-05 11:24 388Sqlite Database 2019(1)Sqlite3 ... -
Supervisor 2019(2)Ubuntu and Multiple Services
2019-08-19 10:53 387Supervisor 2019(2)Ubuntu and Mu ...
相关推荐
Mastering Play Framework for Scala
Leverage the awesome features of Play Framework to build scalable, resilient, and responsive applications First published: May 2015 274page
Mastering Play Framework for Scala 英文无水印pdf pdf使用FoxitReader和PDF-XChangeViewer测试可以打开
Mastering Play Framework for Scala 英文mobi 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Mastering Play Framework for Scala 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
《精通Scala的Play框架》是一本专为Scala开发者设计的深度学习指南,旨在帮助读者全面理解和熟练运用Play框架。Play框架是构建Web应用程序的一个强大工具,尤其在Scala语言的支持下,它提供了高度的灵活性和效率。这...
7. **Actor模型**:Scala内置了Akka框架,支持基于Actor的并发编程,Actor之间通过消息传递实现异步通信,提高了系统的可伸缩性和容错性。 8. ** Trait**:Trait是一种轻量级的抽象类型,可以看作是接口和部分实现...
Harness reactive programming to build scalable and fault-tolerant distributed systems using Scala and Akka About This Book Use the concepts of reactive programming to build distributed systems ...
This book is intended for those developers who are keen to master the internal workings of Play Framework to effectively build and deploy web-related apps.
总之,《Programming in Scala》是一本非常有价值的书籍,无论你是初学者还是有经验的程序员,都能从中获得宝贵的知识和技能。通过本书的学习,你可以更好地理解和运用Scala这一强大而优雅的编程语言。
Play Framework是一種用Scala編寫的Web應用框架,其遵循模型-視圖-控制器建築模式。Play Framework使用Scala編寫,並可以被編譯成Java虛擬機器位元組碼中的其他編程語言使用;例如Java語言。
Play Framework 是一个基于Java和Scala的高性能Web应用框架,它提供了快速开发、可测试和敏捷迭代的能力。在Play Framework中,安全模块是一个重要的组件,它帮助开发者实现基本的认证(Authentication)和授权...
Functional Programming in Scala is a serious tutorial for programmers looking to learn FP and apply it to the everyday business of coding. The book guides readers from basic techniques to advanced ...
本书由直接参与Scala开发的一线人员编写,因而对原理的解读和应用的把握更加值得信赖。本书面向具有一定编程经验的开发者,目标是让读者能够全面了解和掌握Scala编程语言的核心特性,并能够深入理解Scala这门语言在...
Programming in Scala is the definitive book on Scala, the new language for the Java Platform that blends object-oriented and functional programming concepts into a unique and powerful tool for ...
Play Framework 是一个开源的Web应用框架,主要针对Java和Scala开发者设计,它的核心理念是简化开发流程,提高开发效率,并且特别强调了RESTful架构风格。这个“playframework中文教程.zip”压缩包很可能是为了帮助...