2
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

Play Framework 2.6(Scala)でCacheを使ってみた

概要

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
    }  
  }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?