- 浏览: 2489239 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
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 433NodeJS12 and Zlib It works as ... -
Traefik 2020(1)Introduction and Installation
2020-03-29 13:52 295Traefik 2020(1)Introduction and ... -
Private Registry 2020(1)No auth in registry Nginx AUTH for UI
2020-03-18 00:56 378Private Registry 2020(1)No auth ... -
Buffer in NodeJS 12 and NodeJS 8
2020-02-25 06:43 337Buffer in NodeJS 12 and NodeJS ... -
NodeJS ENV Similar to JENV and PyENV
2020-02-25 05:14 419NodeJS ENV Similar to JENV and ... -
Prometheus HA 2020(3)AlertManager Cluster
2020-02-24 01:47 365Prometheus HA 2020(3)AlertManag ... -
Serverless with NodeJS and TencentCloud 2020(5)CRON and Settings
2020-02-24 01:46 294Serverless with NodeJS and Tenc ... -
GraphQL 2019(3)Connect to MySQL
2020-02-24 01:48 211GraphQL 2019(3)Connect to MySQL ... -
GraphQL 2019(2)GraphQL and Deploy to Tencent Cloud
2020-02-24 01:48 394GraphQL 2019(2)GraphQL and Depl ... -
GraphQL 2019(1)Apollo Basic
2020-02-19 01:36 278GraphQL 2019(1)Apollo Basic Cl ... -
Serverless with NodeJS and TencentCloud 2020(4)Multiple Handlers and Running wit
2020-02-19 01:19 266Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(3)Build Tree and Traverse Tree
2020-02-19 01:19 267Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(2)Trigger SCF in SCF
2020-02-19 01:18 255Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(1)Running with Component
2020-02-19 01:17 240Serverless with NodeJS and Tenc ... -
NodeJS MySQL Library and npmjs
2020-02-07 06:21 238NodeJS MySQL Library and npmjs ... -
Python Library 2019(1)requests and aiohttp
2019-12-18 01:12 228Python Library 2019(1)requests ... -
NodeJS Installation 2019
2019-10-20 02:57 519NodeJS Installation 2019 Insta ... -
Monitor Tool 2019(2)Monit on Multiple Instances and Email Alerts
2019-10-18 10:57 232Monitor Tool 2019(2)Monit on Mu ... -
Sqlite Database 2019(1)Sqlite3 Installation and Docker phpsqliteadmin
2019-09-05 11:24 324Sqlite Database 2019(1)Sqlite3 ... -
Supervisor 2019(2)Ubuntu and Multiple Services
2019-08-19 10:53 323Supervisor 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 英文原版数据和代码
Mastering Play Framework for Scala 英文无水印pdf pdf使用FoxitReader和PDF-XChangeViewer测试可以打开
Play Framework is an open source web application framework that is written in Java and Scala. It follows the Model-View-Controller architectural pattern and enables the user to employ Scala for ...
Mastering Play Framework for Scala 英文mobi 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Mastering Play Framework for Scala 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Grok and perform effective functional programming in Scala About This Book Understand functional programming patterns by comparing them with the traditional object-oriented design patterns Write ...
Scala and the functional programming paradigm enable you to solve problems with less code and lower maintenance costs than the alternatives. However, these gains can come at the cost of performance ...
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, 3nd edition
Play Framework是一種用Scala編寫的Web應用框架,其遵循模型-視圖-控制器建築模式。Play Framework使用Scala編寫,並可以被編譯成Java虛擬機器位元組碼中的其他編程語言使用;例如Java語言。
本书由直接参与Scala开发的一线人员编写,因而对原理的解读和应用的把握更加值得信赖。本书面向具有一定编程经验的开发者,目标是让读者能够全面了解和掌握Scala编程语言的核心特性,并能够深入理解Scala这门语言在...
PlayFramework框架安全模块.pdf
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 ...
中文版只有1-13章(已经包括基本应用了) 英文版(全)
scala学习-project.zip
注意是Programming Scala的第二版,而不是Programming in Scala的第二版,更注重于与Spark相关的知识!强烈推荐!Programming Scala- Scalability = Functional Programming + Objects, 2 edition