Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

概要

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
    }  
  }
}
someone7140
まだまだ修行中のエンジニアです。ちゃんとサービスを作れるようになりたいです。
http://toaruit.hatenablog.com/
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした