Playframework(10)Scala Project and Database

Playframework(10)Scala Project and Database
Using the Parser API

The most easiest parser is to parse a value to Scala Long
val rowParser = scalar[Long]

val rsParser = scalar[Long].single

This kind of simple parser API is useful to produce the result by a simple select count query:
val count: Long = SQL("select count(*) from Country").as(scalar[Long].single)

A complex one with str("name") ~ int("population")

val populations:List[String~Int] = {
     SQL("select * from Country").as( str("name") ~ int("population") * )
}

Alternatively, we can write like this:

val result:List[String~Int] = {
     SQL("select * from Country").as(get[String]("name")~get[Int]("population")* )
}

…snip…

8.3 Integrating with other database access libraries
Integrating with ScalaQuery
…snip..
Exposing the datasource through JNDI
…snip...

9. Using the Cache
It is based on Ehcache.

Accessing the Cache API
Using this simple API to store data in cache:
Cache.set("item.key", connectedUser)

retrieve it later:
val maybeUser: Option[User] = Cache.getAs[User]("item.key")

Caching HTTP responses
Play provides a default built-in helper for standard cases:
def index = Cached("homePage"){
     Action{
          Ok("Hello world")
     }
}

10. Calling WebServices
10.1 The Play WS API
Any calls made by play.api.libs.ws.WS should return a Promise[play.api.libs.ws.Response] which we can later handle with Paly's asynchronous mechanisms.

Making an HTTP call
The simple way is to use ws.url().

val homePage: Promise[ws.Response] = WS.url("http://mysite.com").get();

Or:

val result: Promise[ws.Response] = {
     WS.url("http://localhost:9001/post").post("content")
}

Post url-form-encoded data
…snip…

10.2 Connecting to OpenID services
The OpenID flow in a nutshell
1. The user gives you his OpenID(a URL).
2. Your server inspects the content behind the URL to produce a URL where you need to redirect the user.
3. The user confirms the authorization on his OpenID provider, and get redirected back to your server.
4. Your server receives information from that redirect, and checks with the provider that the information is correct.

OpenID in Play
The openID API has 2 import functions:
OpenID.redirectURL. It returns a Promise[String] rather than a String. If the OpenID is invalid, the returned Promise will be a Thrown.

OpenID.verifiedId. It will do a call to the OpenID server to check the authenticity of the information, this is why it returns a Promise[UserInfo] rather than just UserInfo. If the information is not correct or if the server check is false, the returned Promise will be a Thrown.

Here is an example of usage:

def login = Action {
     Ok(views.html.login())
}

def loginPost = Action { implicit request =>
     Form(single(
          "openid" -> nonEmptyText
     )).bindFromRequest.fold(
          error => {
               Logger.info("bad request " + error.toString)
               BadRequest(error.toString)
          },
          {
               case (openid) => AsyncResult(OpenID.redirectURL(openid, routes.Application.openIDCallback.absoluteURL()).extend( _.value match{
                    case Redeemed(url) => Redirect(url)
                    case Throw(t) => Redirect(routes.Application.login)
          }))
          }
     )
}

def openIDCallback = Action { implicit request =>
     AsyncResult(
          OpenID.verifiedId.extend( _.value match {
               case Redeemed(info) => Ok(info.id + "\n" + info.attributes)
               case Thrown(t) => {
                    Redirect(routes.Application.login)
               }
          }
     )
}

Extended Attributes
The OpenID of a user gives you his identity. The protocol also supports getting extended attributes such as the e-mail address, the first name, or the last name.

OpenID.redirectURL(
     openid,
     routes.Application.openIDCallback.absoluteURL(),
     Seq("email" -> "http://schema.openid.net/contact/email")
)

10.3 Accessing resources protected by OAuth
There are 2 very different versions of OAuth: OAuth1.0 and OAuth2.0. Version 2 is simple enough to be implemented easily without library or helpers. Play only provides support for OAuth 1.0.
…snip...

11. Integrating with Akka
…snip…

12. Internationlization
…snip...

13 The application Global object
13.1 Application global settings
The Global object
object Global extends GlobalSettings{
}

Hooking into application start and stop events
Override the onStart and onStop methods to be notified of the events in the application life-cycle:

object Global extends GlobalSettings{
     override def onStart(app: Application) {
          Logger.info("Application has started")
     }

     override def onStop(app: Application) {
          Logger.info("Application shutdown...")
     }
}

Providing an application error page
When an exception occurs in your application, the onError operation will be called.

object Global extends GlobalSettings{
     override def onError(request: RequestHeader, ex: Throwable) = {
          InternalServerError(
               views.html.errorPage(ex)
          )
     }
}

Handling missing actions and binding errors

If the framework doesn't find an Action for a request, the onHandlerNotFound operation will be called:

object Global extends GlobalSettings {
     override def onHandlerNotFound( request: RequestHeader): Result = {
          NotFound(
               views.html.notFoundPage(request.path)
          )
     }
}

onBadRequest is for that if a route was found, but it was not possible to bind the request parameters.

13.2 Intercepting requests
Overriding onRouteRequest
object Global extends GlobalSettings {
     def onRouteRequest( request: RequestHeader): Option[Handler] = {
          println("executed before every request: " + request.toString)
          super.onRouteRequest(request)
     }
}

14 Testing your application
14.1 Writing tests
Using specs2
Unit specifications extend the org.specs2.mutable.Specification trait and are using the should/in format:

class HelloWorldSpec extends Specification{
     "The 'Hello world' string" should {
          "contain 11 characters" in {
               "Hello world" must have size(11)
          }
          "start with 'Hello'" in {
               "Hello world" must startWith("Hello")
          }
          "end with 'world'" in {
               "Hello world" must endWith("world")
          }
     }
}

Running in a fake application
…snip...

References:
http://www.playframework.org/documentation/2.0.4/ScalaHome
http://www.playframework.org/documentation/2.0.4/ScalaAnorm


你可能感兴趣的:(playframework)