概要
ScalaのPlay FrameworkでCacheを使ってみようとしたら、2.6で仕様が変わっていたので、2.6時点での情報整理とサンプルソースの作成をしてみました。
前提
Cacheに関する位置付けはplay framework2.1で認証情報を保持するにてまとめられています。また、2.6での変更点がCache APIs Migrationでまとめられています。この内容を前提として下記にサンプルソースを記します。
サンプルソース
SyncCacheApiを使ったサンプルソースとなります、ユーザのログイン情報を管理するイメージでサンプルを書いています。使い方は従来のCacheとほぼ同様です。セッションキーの管理はControllerで、Cacheの管理はUtilを呼び出す形式としています。
【controllers】
LoginController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import models._
import play.api.data.validation.Valid
import play.api.data.validation.Constraint
import play.api.data.validation.Invalid
import play.api.i18n.I18nSupport
import common.service.LoginUserTable
import models.LoginUser
import play.api.cache._
import models.LoginUser
import common.util.CacheUtil
import java.util.UUID
/**
* Login時に使用するController
*/
@Singleton
class LoginController @Inject()( cache: SyncCacheApi, cc: ControllerComponents) extends AbstractController(cc) with I18nSupport {
var loginUserTable:LoginUserTable = null
// ログインフォーム
val loginUserForm = Form( mapping("userid" -> text.verifying("ユーザIDを入力してください" , {!_.isEmpty()})
, "userpw" -> text.verifying("パスワードを入力してください" , {!_.isEmpty()}) ) (LoginUser.apply)(LoginUser.unapply)
)
// ログイン画面の初期表示
def loginInit() = Action { implicit request =>
// セッションを初期化してログイン画面へ遷移
CacheUtil.deleteSessionUser(cache , request.session.get("sessionKey"))
Ok( views.html.login(loginUserForm) ).withNewSession
}
// ログイン画面のSubmit
def loginSubmit() = Action { implicit request: Request[AnyContent] =>
loginUserForm.bindFromRequest.fold(
// 入力チェックNG
errors => {
BadRequest( views.html.login(errors) )
},
// 入力チェックOK
success => {
// セッションキーを作成
val sessionKey = UUID.randomUUID().toString;
//CacheにUserをセット
CacheUtil.setSessionUser(cache, loginUserTable ,sessionKey)
// セッションにユーザをセットして次画面へ遷移
Redirect("./loginSuccess").withSession("sessionKey" -> sessionKey)
}
)
}
}
LoginSuccessController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import models._
import play.api.data.validation.Valid
import play.api.data.validation.Constraint
import play.api.data.validation.Invalid
import play.api.i18n.I18nSupport
import common.service.LoginUserTable
import common.util.CacheUtil
import play.api.cache._
/**
* Login成功時に使用するController
*/
@Singleton
class LoginSuccessController @Inject()( cache: SyncCacheApi, cc: ControllerComponents) extends AbstractController(cc) with I18nSupport {
// Login成功画面の表示
def loginSuccess() = Action { implicit request =>
// セッションのチェック
CacheUtil.getSessionUser(cache , request.session.get("sessionKey")) match {
case Some(user) =>
// Cacheのセッションの時間を更新するため再セット
CacheUtil.setSessionUser(cache, user , request.session.get("sessionKey"))
// Login成功画面へ遷移
Ok( views.html.loginSuccess() )
case None =>
// ログイン画面へ遷移
Redirect("./login")
}
}
}
【Util】
CacheUtil.scala
package common.util
import common.service.LoginUserTable
import play.api.cache._
import scala.concurrent.duration._
object CacheUtil {
// cacheにユーザをセット(キーがString)
def setSessionUser(cache: SyncCacheApi , loginUserTable:LoginUserTable , sessionkey:String) = {
//CacheにUserをセット(30分)
cache.set(sessionkey, loginUserTable , 30.minutes)
}
// cacheにユーザをセット(キーがOption)
def setSessionUser(cache: SyncCacheApi , loginUserTable:LoginUserTable , sessionkey:Option[String]) = {
sessionkey match{
case Some(key) =>
//CacheにUserをセット(30分)
cache.set(key, loginUserTable , 30.minutes)
case None =>
// 何もしない
}
}
// cacheを削除
def deleteSessionUser(cache: SyncCacheApi, sessionkey:Option[String])= {
sessionkey match{
case Some(key) =>
//Cacheを削除
cache.remove(key)
case None =>
// 何もしない
}
}
// cacheを取得
def getSessionUser( cache: SyncCacheApi , sessionkey:Option[String] ):Option[LoginUserTable]= {
sessionkey match{
case Some(key) =>
// キャッシュからユーザオブジェクトを返す
return cache.get[LoginUserTable](key)
case None =>
// Noneを返す
return None
}
}
}