https://www.playframework.com/documentation/2.6.x/Migration26 を google翻訳した
Play 2.6移行ガイド
これは、Play 2.5からPlay 2.6に移行するためのガイドです。以前のバージョンのPlayから移行する必要がある場合は、まず Play 2.5移行ガイド に従ってください。
移行する方法
sbtでPlayプロジェクトをロード/実行するには、次の手順を実行してsbtビルドを更新する必要があります。
Playアップグレード
play / playins.sbtのPlayバージョン番号を更新してPlayをアップグレードします。
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.x")
2.6.xの "x"は、使用したいPlayのマイナーバージョンです(例:2.6.0)。
0.13.15にsbtをアップグレード
Play 2.6では、最新のsbtバージョン0.13.15にアップグレードする必要があります。 0.13.15のsbtリリースには いくつかの改善とバグ修正 があります( sbt 0.13.13 の変更も参照)。
更新するには、 project/build.properties
を次のように変更します。
sbt.version=0.13.15
Guice DIのサポートが別のモジュールに移動
Play 2.6では、コアPlayモジュールにGuiceが含まれなくなりました。 libraryDependenciesにguiceを追加してGuiceモジュールを設定する必要があります:
libraryDependencies += guice
OpenIDのサポートを別のモジュールに移動
Play 2.6では、コアPlayモジュールは、play.api.libs.openid(Scala)およびplay.libs.openid(Java)にOpenIDサポートを含まなくなりました。これらのパッケージを使用するには libraryDependenciesにopenIdを追加してください:
libraryDependencies += openId
Play JSON を別プロジェクトに移動
Play JSONが https://github.com/playframework/play-json でホストされ別のライブラリに移動しました。 Play JSONはPlayの残りの部分に依存しないので、PlayImportのjson値はSBTビルドではもう機能しません。代わりに、ライブラリを手動で指定する必要があります。
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.0"
また、play-jsonにはコアPlayライブラリとは別のリリースサイクルがあり、バージョンはPlayのバージョンと同期していません。
Play Iteratees を別のプロジェクトに移動
Play Iterateesは、 https://github.com/playframework/play-iteratees でホストされている別のライブラリに移動されました。 Play Iteratees は Playの残りの部分に依存しないため、主な変更点は、ライブラリを手動で指定する必要があることです。
libraryDependencies += "com.typesafe.play" %% "play-iteratees" % "2.6.1"
このプロジェクトには、Iterateesと Reactive Streams を統合するサブプロジェクトもあります。次の依存関係も追加する必要があります。
libraryDependencies += "com.typesafe.play" %% "play-iteratees-reactive-streams" % "2.6.1"
注: ヘルパークラス
play.api.libs.streams.Streams
はplay-iteratees-reactive-streams
に移動され、現在はplay.api.libs.iteratee.streams.IterateStreams
と呼ばれています。したがって、Iteratees依存関係を追加し、必要に応じて新しいクラスを使用する必要があります。
最後に、Play Iterateesは別のバージョン管理方式を採用しているため、バージョンはPlayバージョンと同期しなくなりました。
デフォルトのサーバーエンジンとしてのAkka HTTP
Playはデフォルトのバックエンドとして Akka-HTTP サーバーエンジンを使用します。何らかの理由(たとえば、Nettyの ネイティブトランスポート を使用している場合など)でNettyに戻す必要がある場合は、 Netty Server のマニュアルでその方法を参照してください。
Akka HTTP Server Backend で詳しく読むことができます。
Akka HTTPサーバーのタイムアウト
Play 2.5.xには、デフォルトのサーバーバックエンドである Netty Serverのリクエストタイムアウト設定はありません。しかし、Akka HTTPは、アイドル状態の接続とリクエストの両方にタイムアウトがあります(詳細については、 Akka HTTP Settings のドキュメントを参照してください)。 Akka HTTPドキュメント には、
Akka HTTPには、悪意のある攻撃やプログラミングミスからサーバーを保護するためのさまざまな組み込みのタイムアウトメカニズムが付属しています。
ここ で、 akka.http.server.idle-timeout
、 akka.http.server.request-timeout
、および akka.http.server.bind-timeout
のデフォルト値を確認できます。 Playには タイムアウトを定義するための独自の設定 があります。したがって、503 Service Unavailableの数が表示されるようになったら、設定をアプリケーションにとってより合理的な値に変更することができます。
play.server.http.idleTimeout = 60s
play.server.akka.requestTimeout = 40s
Scalaモードの変更
Scala Mode は Enumeration から case オブジェクトにリファクタリングされました。このリファクタリングにより、ほとんどのScalaコードは変更されません。しかし、あなたのJavaコードでScala Modeの値にアクセスしている場合、それを以下から変更する必要があります:
//このJavaコードを検討する
play.api.Mode scalaMode = play.api.Mode.Test();
次のものに書き直さなければなりません:
//このJavaコードを検討する
play.api.Mode scalaMode = play.Mode.TEST.asScala();
JavaとScalaモード間の変換も簡単です。
// Javaコード内
play.api.Mode scalaMode = play.Mode.DEV.asScala();
またはあなたのScalaコードで:
play.Mode javaMode = play.api.Mode.Dev.asJava
また、 play.api.Mode.Mode
は現在廃止予定です。代わりに play.api.Mode
を使用してください。
Writeable[JsValue]
の変更
以前は、デフォルトのScala Writeable[JsValue]
では暗黙的なコーデックを定義することができました。異なるコーデックを使用して記述することができます。これは、 application/json
がテキストベースのコンテンツタイプのように動作しないため、問題になる可能性があります。 Unicode文字セット(UTF-8、UTF-16およびUTF-32)のみが可能で、多くのテキストベースのコンテンツタイプのように charset
パラメータは定義されていません。
現在、デフォルトの Writeable[JsValue]
には暗黙のパラメータはなく、常に UTF-8 に書き込みます。ほとんどのユーザーはJSONのためにUTF-8を使用したいので、大部分のケースをカバーしています。また、JSONをバイト配列に書き込むためのより効率的な組み込みメソッドを簡単に使用することもできます。
古い動作が必要な場合は、希望のコーデックと Content-Typeの play.api.http.Writeable.writeableOf_JsValue(codec, contentType)
を使用して任意のコーデックで書き込み可能を定義できます。
Scala コントローラの変更
慣用的なPlayコントローラは、これまで、必要なグローバル状態を有していた。必要な主要な場所は、グローバル Action オブジェクトと BodyParsers#parse
メソッドでした。
その状態を注入する新しい方法をいくつかの新しいコントローラクラスに提供し、同じ構文を提供しました:
- BaseController :インプリメンテーションクラスによって提供される抽象 ControllerComponents を持つトレイト。
- AbstractController :コンストラクタインジェクションを使用して注入できる ControllerComponents コンストラクタパラメータで BaseController を拡張する抽象クラス。
-
InjectedController :メソッド挿入(
setControllerComponents
メソッドを呼び出す)によって ControllerComponents を取得する、 BaseController を拡張する特性。 GuiceのようなランタイムDIフレームワークを使用している場合、これは自動的に行われます。
ControllerComponents は、コントローラで一般的に使用されるコンポーネントをバンドルするためのものです。 ControllerHelpers を拡張し、独自のコンポーネントバンドルを注入することで、独自のベースコントローラを作成することもできます。 Playでは、コントローラが特定の特性を実装する必要はありません。
BaseController は、 Action と parse
が、グローバルオブジェクトではなく、注入されたインスタンスを参照するようにします。これは、通常は実行したいものです。
AbstractController を使用したコードの例を次に示します。
class FooController @Inject() (components: ControllerComponents)
extends AbstractController(components) {
// Action and parse now use the injected components
def foo = Action(parse.json) {
Ok
}
}
BaseController の場合:
class FooController @Inject() (val controllerComponents: ControllerComponents) extends BaseController {
// Action and parse now use the injected components
def foo = Action(parse.json) {
Ok
}
}
InjectedController の場合:
class FooController @Inject() (val controllerComponents: ControllerComponents) extends BaseController {
// Action and parse now use the injected components
def foo = Action(parse.json) {
Ok
}
}
InjectedController
は、JSR-330準拠の依存関係注入によって自動的に呼び出される setControllerComponents
メソッドを呼び出すことによって ControllerComponents
を取得します。コンパイル時DIで InjectedController
を使用することはお勧めしません。コントローラを手作業で広範囲にユニットテストする予定がある場合は、 InjectedController
が依存関係を隠すので避けることをおすすめします。
個別の依存関係を手動で渡すことを希望する場合は、代わりにそれを行い、依存関係や状態のない ControllerHelpers を拡張することができます。ここに例があります:
class Controller @Inject() (
action: DefaultActionBuilder,
parse: PlayBodyParsers,
messagesApi: MessagesApi
) extends ControllerHelpers {
def index = action(parse.text) { request =>
Ok(messagesApi.preferred(request)("hello.world"))
}
}
Scala ActionBuilderとBodyParserの変更点
Scala ActionBuilder のトレイトは、ボディの型を型パラメータとして指定し、抽象パーサメンバをデフォルトボディパーサとして追加するように変更されました。あなたはあなたの ActionBuilder を修正し、ボディパーサを直接渡す必要があります。
Action グローバルオブジェクトと BodyParsers#parse
は現在廃止予定です。それらはそれぞれ注入可能なトレイト、 DefaultActionBuilder および PlayBodyParsers に置き換えられます。コントローラの中にいる場合は、新しい BaseController トレイトによって自動的に提供されます(上記の [Scala コントローラの変更] を参照してください)。
クッキー
Javaユーザーの場合、 play.mvc.Http.Cookie.builder を使用して新しい Cookie を作成することをお勧めします。
Http.Cookie cookie = Cookie.builder("color", "blue")
.withMaxAge(3600)
.withSecure(true)
.withHttpOnly(true)
.withSameSite(SameSite.STRICT)
.build();
これは普通のコンストラクタ呼び出しよりも読みやすく、今後クッキー属性を追加/削除するとソースと互換性があります。
SameSite属性(セッションとフラッシュ用に有効)
現在、Cookieには SameSite属性 が追加されており、CSRFを防止するために使用できます。次の3つの状態が考えられます。
-
SameSite
がない。つまり、そのドメインへのすべてのリクエストに対してCookieが送信されます。 -
SameSite=Strict
クロスサイトリクエストではなく、同じサイトリクエスト(サイトの別のページからのもの)に対してのみクッキーが送信されることを意味します。 -
SameSite=Lax
つまり、トップレベルのナビゲーションとしてクロスサイトリクエストに対してクッキーが送信されますが、それ以外の場合は同じサイトリクエストに対してのみ送信されます。これにより、ほとんどのサイトで正しいことが実行されますが、ポップアップウィンドウを起動して実行される攻撃などの特定の種類の攻撃は防げません。
さらに、デフォルトで SameSite=Lax
を使用するようにセッションCookieとFlash Cookieを移動しました。設定を使ってこれを微調整することができます。例えば:
play.http.session.sameSite = null // no same-site for session
play.http.flash.sameSite = "strict" // strict same-site for flash
注:この機能は現在、 多くのブラウザでサポートされていない ため、使用しないでください。 ChromeとOperaは現在SameSiteをサポートする唯一の主要なブラウザです。
__Host
と __Secure
プレフィックス
また、 __Host
と __Secure
のCookie名のプレフィックス もサポートしました。
これは、Cookie名にこれらのプレフィックスを使用している場合にのみ影響します。もしあなたがそうであれば、適切な属性が設定されていない場合、それらのクッキーをシリアライズおよびデシリアライズするときにPlayが警告し、自動的にそれらを設定します。警告を削除するには、Cookieにこれらの接頭辞を使用しないか、次のように属性を設定する必要があります。
-
__Host-
で指定されたCookieは、Path=/
およびSecure
属性を設定する必要があります。 -
__Secure-
で名前が付けられたCookieは、Secure
属性を設定する必要があります。
Assets
コンパイル時DIを使用したアセットのバインド
コンパイル時DIを使用している場合は、 controllers.AssetsComponents をミックスインして、コントローラインスタンスで assets:Asset
を取得する必要があります。
class MyComponents(context: Context) extends BuiltInComponentsFromContext(context) with AssetsComponents {
lazy val router = new Routes(httpErrorHandler, assets)
}
lazy val assets: Assets
を持つ場合は、削除することができます。
Assets の構成
既存のユーザー向けAPIは変更されていませんが、AssetsFinder APIに移り、アセットを探し、設定でアセットディレクトリを設定することをお勧めします。
play.assets {
path = "/public"
urlPrefix = "/assets"
}
ルートでは次のことができます:
# prefix must match `play.assets.urlPrefix`
GET /assets/*file controllers.Assets.at(file)
GET /versionedAssets/*file controllers.Assets.versioned(file)
引数リストの先頭にアセットのパスを指定する必要はなくなりました。これは設定から読み込まれるためです。
テンプレートでは、 AssetsFinder#path
を使ってアセットの最終パスを見つけることができます:
@(assets: AssetsFinder)
<img alt="hamburger" src="@assets.path("images/hamburger.jpg")">
Assets.versioned
を使用して引き続き逆ルートを使用することはできますが、複数のアプリケーションを一度に実行する場合は、問題の原因になる可能性がある最終的なアセット名に指定したアセット名を変換する必要があります。
フォームの変更
Play 2.6以降、POST、PUT、またはPATCHリクエストと組み合わせて bindFromRequest() を使用すると、クエリ文字列パラメータはフォームインスタンスにバインドされなくなります。
このリリースでは、2.5で既に廃止されていた静的メソッド( DynamicForm.form()
など)は削除されました。移行方法について詳しくは、 Play 2.5移行ガイド を参照してください。
Javaフォームの変更
play.data.Form インスタンスの errors() メソッドは廃止予定です。 Map> の代わりに単純な List を返す allErrors()
を代わりに使用する必要があります。 Play 2.6以前では .errors().get("key")
を呼び出したところで、単に .errors("key")
を呼び出すことができます。
これ以降、フォームクラス内で実装された validate
メソッド(通常はクロスフィールド検証に使用される)は、クラスレベルの制約の一部です。このような制約の使用方法の詳細については、 高度な検証ドキュメント を参照してください。
影響を受けるフォームクラスに @Validate
で注釈を付け、 validate
メソッドの戻り値の型に応じて、適切なtype引数(すべてが play.data.validation.Constraints で定義されています)で Validatable インターフェイスを実装することで、既存の validate
メソッドを簡単に移行できます:
|戻り値の型|実装するインタフェース|
|--------+----------------|
|String | Validatable|
|ValidationError | Validatable|
|List | Validatable>|
|Map> (not supported anymore; use List instead) | Validatable>|
(これ以上サポートされていない; Listを代わりに使用する)Validatable >
たとえば、次のような既存のフォーム:
public class MyForm {
//...
public String validate() {
//...
}
}
変更する必要があります:
import play.data.validation.Constraints.Validate;
import play.data.validation.Constraints.Validatable;
@Validate
public class MyForm implements Validatable<String> {
//...
@Override
public String validate() {
//...
}
}
注意:以前のすべての制約が以前に成功した後にのみ、「古い」検証メソッドが呼び出されました。しかし、デフォルトでは、クラスレベルの制約は、他の制約アノテーションと同時に呼び出されます(パスの合否に関係なく)。制約間に順序を定義するために、制約グループを使用できるようになりました。
JPA移行ノート
JPA移行ノート を参照してください。
I18n移行ノート
「I18N APIの移行」 を参照してください。
キャッシュAPI移行ノート
「キャッシュAPIの移行」 を参照してください。
Java Configuration API移行ノート
Java Configuration Migration を参照してください。
Scala 設定API
Scalaの play.api.Configuration APIには、 ConfigLoader を使用してあらゆるタイプの読み込みを可能にする新しいメソッドが追加されました。これらの新しい方法では、構成ファイルに構成キーが存在することが期待されます。たとえば、次の古いコードです。
val myConfig: String = configuration.getString("my.config.key").getOrElse("default")
変更する必要があります
val myConfig: String = configuration.get[String]("my.config.key")
my.config.key = default
という設定で値 "default" を設定する必要があります。
また、デフォルト値を取得するためにコードでカスタムロジックが必要な場合は、設定ファイル( my.config.key = null
)でデフォルトをnullに設定し、 Option[T]
を読むことができます。
val myConfigOption: Option[String] = configuration.get[Option[String]]("my.config.key")
val myConfig: String = myConfigOption.getOrElse(computeDefaultValue())
また、 getBooleanList
のようなJava型を返す古い play.api.Configuration にはいくつかのメソッドがあります。可能であれば、Scalaバージョンの get[Seq[Boolean]]
を使用することをお勧めします。それが不可能な場合は、基礎となる underling
Config オブジェクトにアクセスし、そこから getBooleanList
を呼び出すことができます。
既存のメソッドの非推奨メッセージには、各メソッドの移行方法も説明されています。 play.api.Configuration の適切な使い方の詳細については、Scala Configurationドキュメント を参照してください。
Play JSON APIの変更
JSON配列インデックスの参照
Scala play-json APIを使用している場合は、JsLookup暗黙クラスの動作に少し変更があります。たとえば、次のようなコードがあるとします。
val bar = (jsarray(index) \ "bar").as[Bar]
indexは配列インデックスで、jsarrayはJsArrayです。これで、次のように記述する必要があります。
val bar = (jsarray \ index \ "bar").as[Bar]
これは、Scalaの他のコレクションのインデックスに沿った JsArrays
のインデックス作成の動作を実現するために行われました。これで、 jsarray(index)
メソッドはインデックスの値を返し、存在しなければ例外をスローします。
削除されたAPI
削除されたCrypto API
Crypto APIは、廃止予定のクラス play.api.libs.Crypto、play.libs.Crypto
および AESCTRCrypter
を削除しました。 Crypto
へのCSRF参照は CSRFTokenSigner
に置き換えられました。 Crypto
へのセッションCookieの参照が CookieSigner
に置き換えられました。詳細については、 CryptoMigration25 を参照してください。
Akka廃止されたメソッドが削除されました
廃止予定の静的メソッド play.libs.Akka.system
および play.api.libs.concurrent.Akka.system
が削除されました。依存関係注入を使用して ActorSystem
のインスタンスを取得し、アクターシステムにアクセスします。
Scalaの場合:
class MyComponent @Inject() (system: ActorSystem) {
}
Javaの場合:
public class MyComponent {
private final ActorSystem system;
@Inject
public MyComponent(ActorSystem system) {
this.system = system;
}
}
また、Play 2.6.xではAkka 2.5.xリリースシリーズが使用されるようになりました。必要に応じて、独自のコードを適用する方法については、 2.4.xから2.5.xへのAkka移行ガイド をお読みください。
削除されたYaml API
私たちは play.libs.Yaml
を削除しました。Play の中にもうそれを使用していなかったからです。 Play YAMLの統合をサポートする必要がある場合は、 snakeyaml
を build.sbt
に追加する必要があります。
libraryDependencies += "org.yaml" % "snakeyaml" % "1.17"
あなたのコードに以下のWrapperを作成します:
public class Yaml {
private final play.Environment environment;
@Inject
public Yaml(play.Environment environment) {
this.environment = environment;
}
/**
* Load a Yaml file from the classpath.
*/
public Object load(String resourceName) {
return load(
environment.resourceAsStream(resourceName),
environment.classLoader()
);
}
/**
* Load the specified InputStream as Yaml.
*
* @param classloader The classloader to use to instantiate Java objects.
*/
public Object load(InputStream is, ClassLoader classloader) {
org.yaml.snakeyaml.Yaml yaml = new org.yaml.snakeyaml.Yaml(new CustomClassLoaderConstructor(classloader));
return yaml.load(is);
}
}
またはScalaで:
class Yaml @Inject()(environment: play.api.Environment) {
def load(resourceName: String) = {
load(environment.resourceAsStream(resourceName), environment.classLoader)
}
def load(inputStream: InputStream, classLoader: ClassLoader) = {
new org.yaml.snakeyaml.Yaml(new CustomClassLoaderConstructor(classloader)).load(inputStream)
}
}
Playの代替DIライブラリに明示的に依存している場合、または独自のカスタムアプリケーションローダーを定義している場合は、変更は必要ありません。
Play DIサポートを提供するライブラリは、 play.application.loader
設定キーを定義する必要があります。外部DIライブラリが提供されていない場合は、 ApplicationLoader をポイントしない限り、Playは起動を拒否します。
廃止予定の play.Routes
を削除しました。
JavaScriptルータを作成するために使用された廃止予定のplay.Routesクラスが削除されました。新しいJavaまたはScalaヘルパーを使用する必要があります。
削除されたライブラリ
デフォルトのプレイ配布を少し小さくするために、いくつかのライブラリを削除しました。以下のライブラリは、もはやPlay 2.6の依存関係ではありませんので、使用する場合は手動でビルドに追加する必要があります。
joda-time の削除
java.time
APIを使用することをお勧めします。そのため、Playのコアからjoda-timeサポートを削除します。
PlayのScalaフォームライブラリには、いくつかのJodaフォーマットがありました。移行しない場合は、jodaFormsモジュールをbuild.sbtに追加できます。
libraryDependencies += jodaForms
そして、対応するオブジェクトをインポートします:
import play.api.data.JodaForms._
play-jsonでJodaサポートが必要な場合は、次の依存関係を追加できます。
libraryDependencies += "com.typesafe.play" %% "play-json-joda" % playJsonVersion
ここで、playJsonVersionは使用したいplay-jsonバージョンです。 Play 2.6.xはplay-json 2.6.xと互換性があります。 play-jsonは別のプロジェクトになりました(後述)。
import play.api.libs.json.JodaWrites._
import play.api.libs.json.JodaReads._
Joda-Convertの削除
あなたがあなたのプロジェクトでそれをあなたのbuild.sbtに追加する必要があるならば、playはjoda-convertの内部使用をいくつか持っていました:
libraryDependencies += "org.joda" % "joda-convert" % "1.8.1"
XercesImplの削除
XML処理の場合PlayはXerces XML Libraryを使用しました。現代のJVMは参照実装としてXercesを使用しているので、それを削除しました。プロジェクトが外部パッケージに依存している場合は、単純にbuild.sbtに追加することができます。
libraryDependencies += "xerces" % "xercesImpl" % "2.11.0"
H2除去
以前のバージョンのPlayでは、H2データベースがプリインストールされていました。しかし、Playのコアを小さくするために、削除しました。 H2を使用する場合は、それをbuild.sbtに追加することができます:
libraryDependencies += "com.h2database" % "h2" % "1.4.193"
テストでのみ使用した場合は、Testスコープを使用することもできます。
libraryDependencies += "com.h2database" % "h2" % "1.4.193" % Test
依存関係を追加した後でもH2ブラウザは動作します。
snakeyaml 除去
play.libs.Yaml
を削除しました。したがって、 snakeyaml
への依存関係は削除されました。まだ使用している場合は、 build.sbt
に追加してください:
libraryDependencies += "org.yaml" % "snakeyaml" % "1.17"
[Yaml APIの削除に関する注意] も参照してください。
Tomcat-servlet-apiの削除
tomcat-servlet-api
は使用されていなかったので、Playで削除されました。まだ使用している場合は、 build.sbt
に追加してください:
libraryDependencies += "org.apache.tomcat" % "tomcat-servlet-api" % "8.0.33"
リクエスト属性
すべての要求オブジェクトに属性が含まれるようになりました。リクエスト属性は、リクエストタグの代わりとなります。タグは廃止され、属性にアップグレードする必要があります。属性はタグより強力です。属性を使用してオブジェクトを要求に格納できますが、タグはストリングの格納のみをサポートしています。
リクエストタグの非推奨
タグは廃止されましたので、タグを使用してから属性を使用するように移行する必要があります。マイグレーションはかなり簡単です。
最も簡単な移行パスは、タグからString型の属性に移行することです。
以前のJava:
// Getting a tag from a Request or RequestHeader
String userName = req.tags().get("userName");
// Setting a tag on a Request or RequestHeader
req.tags().put("userName", newName);
// Setting a tag with a RequestBuilder
Request builtReq = requestBuilder.tag("userName", newName).build();
これからのJava:
class Attrs {
public static final TypedKey<String> USER_NAME = TypedKey.<String>create("userName");
}
// Getting an attribute from a Request or RequestHeader
String userName = req.attrs().get(Attrs.USER_NAME);
String userName = req.attrs().getOptional(Attrs.USER_NAME);
// Setting an attribute on a Request or RequestHeader
Request newReq = req.withTags(req.tags().put(Attrs.USER_NAME, newName));
// Setting an attribute with a RequestBuilder
Request builtReq = requestBuilder.attr(Attrs.USER_NAME, newName).build();
以前のScala:
// Getting a tag from a Request or RequestHeader
val userName: String = req.tags("userName")
val optUserName: Option[String] = req.tags.get("userName")
// Setting a tag on a Request or RequestHeader
val newReq = req.copy(tags = req.tags.updated("userName", newName))
これからのScala:
object Attrs {
val UserName: TypedKey[String] = TypedKey("userName")
}
// Getting an attribute from a Request or RequestHeader
val userName: String = req.attrs(Attrs.UserName)
val optUserName: [String] = req.attrs.get(Attrs.UserName)
// Setting an attribute on a Request or RequestHeader
val newReq = req.addAttr(Attrs.UserName, newName)
ただし、適切な場合は、StringタグをString以外の値を持つ属性に変換することをお勧めします。タグをString以外のオブジェクトに変換すると、いくつかの利点があります。まず、コードの型をより安全にします。これにより、コードの信頼性が向上し、理解しやすくなります。次に、属性に格納するオブジェクトには複数のプロパティを含めることができるため、複数のタグを単一の値に集約できます。第3に、タグを属性に変換すると、文字列の値をエンコードしてデコードする必要がなくなるため、パフォーマンスが向上する可能性があります。
class Attrs {
public static final TypedKey<User> USER = TypedKey.<User>create("user");
}
後のスカラ:
object Attrs {
val UserName: TypedKey[User] = TypedKey("user")
}
FakeRequest.withCookies を呼び出すと Cookies ヘッダーが更新されなくなりました
リクエストクッキーはリクエスト属性に格納されるようになりました。以前は、リクエストの Cookie ヘッダ文字列に格納されていました。これは、クッキーが変更されるたびにヘッダーにクッキーをエンコードしてデコードする必要がありました。
クッキーがリクエスト属性に格納されるようになったので、クッキーを更新すると新しいクッキー属性は変更されますが、Cookie HTTPヘッダーは変更されません。これは、 withCookies
を呼び出してヘッダを更新する場合にのみ、テストに影響します。
それでもなお古い動作が必要な場合は、 Cookies.encodeCookieHeader を使用してCookieオブジェクトをHTTPヘッダーに変換し、 FakeRequest.withHeaders
でヘッダーを保存することができます。
play.api.mvc.Security.username (Scala API)、session.username 変更
play.api.mvc.Security.username
(Scala API)、 session.username
設定キーおよび依存アクションヘルパーは推奨されていません。 Security.username
は、設定から session.username
キーを取得するだけで、ユーザー名を取得するために使用されたセッションキーが定義されています。静的な動作が必要なため削除されました。同一または類似の動作を自分で実装するのはかなり簡単です。
configuration.get[String]( "session.username")
を使用して、設定からユーザー名セッションキーを読み取ることができます。
Authenticated(String => EssentialAction)
メソッドを使用している場合は、簡単に独自のアクションを作成して同様のことを行うことができます。
def AuthenticatedWithUsername(action: String => EssentialAction) =
WithAuthentication[String](_.session.get(UsernameKey))(action)
UsernameKeyは、ユーザー名に使用するセッションキーを表します。
リクエストセキュリティ(Java API)ユーザ名プロパティが属性になりました
Java Requestオブジェクトには、Security.AuthenticatedアノテーションがJavaアクションに追加されたときに設定される username
プロパティが含まれています。 Play 2.6では、 username
プロパティは廃止されました。 usernameプロパティのメソッドが更新され、 Security.USERNAME
属性にユーザー名が格納されます。 Security.USERNAME
属性を直接使用するようにコードを更新する必要があります。 Playの将来のバージョンでは、 username
プロパティを削除します。
この変更の理由は、usernameプロパティが Security.Authenticated
アノテーションの特別なケースとして提供されたためです。これで特別なケースは必要なくなりました。
既存のJavaコード:
// Set the username
Request reqWithUsername = req.withUsername("admin");
// Get the username
String username = req1.username();
// Set the username with a builder
Request reqWithUsername = new RequestBuilder().username("admin").build();
アップデートされたJavaコード:
import play.mvc.Security.USERNAME;
// Set the username
Request reqWithUsername = req.withAttr(USERNAME, "admin");
// Get the username
String username = req1.attr(USERNAME);
// Set the username with a builder
Request reqWithUsername = new RequestBuilder().putAttr(USERNAME, "admin").build();
ルータタグは属性になりました
Router.Tags.*
タグを使用した場合は、新しい Router.Attrs.HandlerDef (Scala) または Router.Attrs.HANDLER_DEF (Java)属性を使用するようにコードを変更する必要があります。 既存のタグは引き続き使用できますが、廃止され、今後のバージョンのPlayで削除されます。
この新しい属性には、現在タグ内にあるすべての情報を含む HandlerDef
オブジェクトが含まれています。 現在のタグは、すべてHandlerDefオブジェクトのフィールドに対応します。
|Javaタグ名|Scalaタグ名|HandlerDefメソッド|
+-------+-----------+----------------+
|ROUTE_PATTERN | RoutePattern | path|
|ROUTE_VERB | RouteVerb |verb|
|ROUTE_CONTROLLER | RouteController |controller|
|ROUTE_ACTION_METHOD | RouteActionMethod |method|
|ROUTE_COMMENTS | RouteComments |comments|
注:この変更の一環として、
HandlerDef
オブジェクトがplay.core.routing
内部パッケージからplay.api.routing
パブリックAPIパッケージに移動されました。
play.api.libs.concurrent.Executionは推奨されていません
play.api.libs.concurrent.Execution
クラスは、"現在の" アプリケーションのExecutionContextをプルするためにグローバルな可変状態を使用していたため、廃止されました。
以前に行った暗黙的な動作を指定する場合は、 依存関係注入 を使用してコンストラクタに暗黙的に実行コンテキストを渡す必要があります。
class MyController @Inject()(implicit ec: ExecutionContext) {
}
コンパイル時依存関係注入を使用している場合はBuiltInComponentsから取得します。
class MyComponentsFromContext(context: ApplicationLoader.Context)
extends BuiltInComponentsFromContext(context) {
val myComponent: MyComponent = new MyComponent(executionContext)
}
ただし、一般的な場合でも実行コンテキストをインポートしたくない理由がいくつかあります。一般的なケースでは、アプリケーションの実行コンテキストは、アクションのレンダリングや、APIコールや I/O アクティビティのブロックに関係しないCPUバウンドアクティビティの実行に適しています。データベースを呼び出す場合やネットワーク呼び出しを行う場合は、独自のカスタム実行コンテキストを定義することができます。
カスタム実行コンテキストを作成するには、 Custom ExecutionContext を使用することをお勧めします。これは、Akkaディスパッチャシステム(java / scala )を使用して、エグゼキュータをコンフィグレーションで定義できるようにします。
独自の実行コンテキストを使用するには、 CustomExecutionContext 抽象クラスを application.conf
ファイルのディスパッチャへのフルパスで拡張します。
import play.api.libs.concurrent.CustomExecutionContext
class MyExecutionContext @Inject()(actorSystem: ActorSystem)
extends CustomExecutionContext(actorSystem, "my.dispatcher.name")
import play.libs.concurrent.CustomExecutionContext;
class MyExecutionContext extends CustomExecutionContext {
@Inject
public MyExecutionContext(ActorSystem actorSystem) {
super(actorSystem, "my.dispatcher.name");
}
}
必要に応じてカスタム実行コンテキストを注入します。
class MyBlockingRepository @Inject()(implicit myExecutionContext: MyExecutionContext) {
// do things with custom execution context
}
カスタムスレッドプール設定の詳細については、 ThreadPools ページを、CustomExecutionContextを使用する場合は JavaAsync / ScalaAsync を参照してください。
play.api.testヘルパーへの変更
推奨されない次のテストヘルパーは、2.6.xで削除されました。
-
play.api.test.FakeApplication
はplay.api.inject.guice.GuiceApplicationBuilder
に置き換えられました。 -
play.api.test.Helpers.route(request)
はplay.api.test.Helpers.routes(app, request)
メソッドに置き換えられました。 -
play.api.test.Helpers.route(request, body)
はplay.api.test.Helpers.routes(app, request, body)
メソッドに置き換えられました。
Java API
-
play.test.FakeRequest
が RequestBuilder に置き換えられました -
play.test.FakeApplication
はplay.inject.guice.GuiceApplicationBuilder
に置き換えられました。 play.test.Helpers.fakeApplication から新しいアプリケーションを作成できます。 -
play.test.WithApplication
では、廃止予定のprovideFakeApplication
メソッドが削除されました。provideApplication
メソッドを使用する必要があります。
テンプレートヘルパーの変更
views/helper/requireJs.scala.html の requireJs テンプレートヘルパーは、 Play.maybeApplication
を使用して設定にアクセスしました。
requireJs
テンプレートヘルパーには、追加されたヘルパーのバージョンを使用する必要があるかどうかを示す追加パラメータ isProd
が追加されています。
@requireJs(core = routes.Assets.at("javascripts/require.js").url, module = routes.Assets.at("javascripts/main").url, isProd = true)
MIMEタイプマッピングへのファイル拡張の変更
ファイル拡張子のMIMEタイプへのマッピングは、 reference.conf
に移動されているので、 play.http.fileMimeTypes
設定の下で、設定を通して完全にカバーされています。以前は、リストは play.api.libs.MimeTypes
の下にハードコードされていました。
play.http.fileMimeTypes
の設定は、トリプルクォートを単一の文字列として定義していることに注意してください。これは、複数のファイル拡張子に c++
などの HOCON を壊す構文があるためです。
カスタムMIMEタイプを追加するには、 HOCON文字列値の連結 を使用します。
play.http.fileMimeTypes = ${play.http.fileMimeTypes} """
foo=text/bar
"""
MIMEタイプを追加するために mimetype.foo=text/bar
として定義された設定を可能にする構文があります。これは推奨されていません。上記の設定を使用することをお勧めします。
Java API
Http.Context.current().fileMimeTypes()
メソッドは、 Results.sendFile
のフードの下にあり、ファイル拡張子からコンテンツタイプを検索するその他のメソッドがあります。移行は必要ありません。
Scala API
play.api.libs.MimeTypes
クラスが play.api.http.FileMimeTypes インターフェイスに変更され、実装が play.api.http.DefaultFileMimeTypes に変更されました。
ファイルまたはリソースを送信するすべての結果は、暗黙的に FileMimeTypes
をとります。
implicit val fileMimeTypes: FileMimeTypes = ...
Ok(file) // <-- takes implicit FileMimeTypes
FileMimeTypes
の暗黙のインスタンスは、便利なバインディングを提供するために、 BaseController
(およびそのサブクラス AbstractController
およびsubtrait InjectedController
)によって ControllerComponents
クラスによって提供されます。
class SendFileController @Inject() (cc: ControllerComponents) extends AbstractController(cc) {
def index() = Action { implicit request =>
val file = readFile()
Ok(file) // <-- takes implicit FileMimeTypes
}
}
単体テストで完全に構成されたFileMimeTypesインスタンスを直接取得することもできます。
val httpConfiguration = new HttpConfigurationProvider(Configuration.load(Environment.simple)).get
val fileMimeTypes = new DefaultFileMimeTypesProvider(httpConfiguration.fileMimeTypes).get
またはカスタムのものを入手する:
val fileMimeTypes = new DefaultFileMimeTypesProvider(FileMimeTypesConfiguration(Map("foo" -> "text/bar"))).get
デフォルトのフィルタ
Play には、設定によって定義された有効なフィルタのデフォルトセットが付属しています。 play.http.filters
プロパティがnullの場合、デフォルトは play.filters.enabled
設定プロパティの完全修飾クラス名で定義されたフィルタをロードする play.api.http.EnabledFilters になります。
Play 自体では、 play.filters.enabled
は空のリストです。ただし、フィルタライブラリは自動的に PlayFilters
という AutoPlugin として SBT にロードされ、次の値が play.filters.enabled
プロパティに追加されます。
- play.filters.csrf.CSRFFilter
- play.filters.headers.SecurityHeadersFilter
- play.filters.hosts.AllowedHostsFilter
つまり、新しいプロジェクトでは、CSRF保護( ScalaCsrf / JavaCsrf )、 SecurityHeaders および AllowedHostsFilter はすべて自動的に定義されます。
デフォルトフィルタの効果
既定のフィルタは、プロジェクトに「デフォルトでセキュリティで保護された」構成を与えるように構成されています。
これらのフィルタは有効にしておく必要があります。アプリケーションをより安全にするためです。
既存のプロジェクトでこれらのフィルタを有効にしていない場合は、いくつかの設定が必要となり、関連するエラーや失敗に精通していない可能性があります。移行を支援するために、各フィルタ、そのフィルタ、必要な設定について説明します。
CSRFFilter
CSRFフィルタについては ScalaCsrf と JavaCsrf で説明しています。これは、POSTリクエストでチェックされるフォームにCSRFトークンを追加することにより、 クロスサイト要求偽造攻撃 から保護します。
デフォルトで有効になっている理由
CSRFは非常に一般的な攻撃であり、実装に必要なスキルはほとんどありません。 Playを使用してCSRF攻撃の例を見ることができます(https://github.com/Manc/play-scala-csrf)。
どのような変更が必要ですか?
CSRF.formField
などのCSRFフォームヘルパを使用しない既存のプロジェクトから移行する場合は、CSRFフィルタのPUTおよびPOSTリクエストに「403 Forbidden」が表示されることがあります。
CSRF.formField
をフォームテンプレートに追加するとエラーが解決されます。AJAXでリクエストを作成する場合は、HTMLページにCSRFトークンを置き、 Csrf-Token
ヘッダーを使用して要求に追加できます。
この動作を確認するには、 logback.xml
に <logger name = "play.filters.csrf" value = "TRACE" />
を追加してください。
また、 Play の SameSite Cookie を有効にして、CSRF攻撃に対する追加防御を提供することもできます。
SecurityHeadersFilter
SecurityHeadersFilter は、リクエストに余分なHTTPヘッダーを追加することで、 クロスサイトスクリプティング と クリックジャック攻撃 を防ぎます。
デフォルトで有効になっている理由
ブラウザベースの攻撃は非常に共通しています。セキュリティヘッダーは、これらの攻撃を阻止するための深い防御を提供します。
どのような変更が必要ですか?
デフォルトの "Content-Security-Policy" の設定は非常に厳密です。最も有用な設定を見つけるには、それを試す必要があります。コンテンツセキュリティポリシーの設定では、Javascriptとリモートフレームがブラウザにどのように表示されるかが変更されます。 Content-Security-Policyヘッダーを変更するまで、埋め込まれたJavascriptまたはCSSはWebページに読み込まれません。
有効にしたくない場合は、次のようにContent-Security-Policyを無効にすることができます。
play.filters.headers.contentSecurityPolicy=null
CSP-Useful は、一般的な Content-Security-Policy の優れたリソースです。すべてのリクエストにカスタムCSPナンスを追加するなど、埋め込まれたJavascriptに対する他の潜在的な解決策があることに注意してください。
他のヘッダーは侵入性が低く、プレーンなWebサイトで問題を引き起こす可能性は低いですが、シングルページアプリケーションでCookieやレンダリングの問題が発生する可能性があります。 Mozillaには、URLのヘッダ名を使用して、各ヘッダを詳細に記述するドキュメントがあります。たとえば、X-Frame-Optionsの場合は https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options に行きます。
play.filters.headers {
# The X-Frame-Options header. If null, the header is not set.
frameOptions = "DENY"
# The X-XSS-Protection header. If null, the header is not set.
xssProtection = "1; mode=block"
# The X-Content-Type-Options header. If null, the header is not set.
contentTypeOptions = "nosniff"
# The X-Permitted-Cross-Domain-Policies header. If null, the header is not set.
permittedCrossDomainPolicies = "master-only"
# The Content-Security-Policy header. If null, the header is not set.
contentSecurityPolicy = "default-src 'self'"
# The Referrer-Policy header. If null, the header is not set.
referrerPolicy = "origin-when-cross-origin, strict-origin-when-cross-origin"
# If true, allow an action to use .withHeaders to replace one or more of the above headers
allowActionSpecificHeaders = false
}
AllowedHostsFilter
AllowedHostsFilter は、許可されたホストのホワイトリストを追加し、ホワイトリストと一致しないホストを持つすべての要求に 400(Bad Request) 応答を送信します。
デフォルトで有効になっている理由
DNSリバインディング攻撃は、開発者のPlayのインスタンスに対して使用できるため、開発で使用する重要なフィルタです。短期間のDNS再バインドがlocalhost上で動作するサーバを攻撃する方法の例については、Rails Webconsole DNS Rebinding を参照してください。
どのような変更が必要ですか?
localhost 以外のアプリケーションでPlayアプリケーションを実行している場合は、 AllowedHostsFilter を設定して、接続先の ホスト名/IP を特に許可する必要があります。通常、開発環境ではlocalhostで実行されますが、ステージングや本番環境ではリモートで実行されるため、環境を変更するときに注意する必要があります。
play.filters.hosts {
# Allow requests to example.com, its subdomains, and localhost:9000.
allowed = [".example.com", "localhost:9000"]
}
フィルタに追加する
デフォルトリストに追加するには、 +=
:
play.filters.enabled+=MyFilter
play.api.http.DefaultHttpFilters
を拡張して独自のフィルタを定義した場合、 EnabledFilters
とコード内の独自のリストを組み合わせることもできます。これまでにプロジェクトを定義していたとしても、通常どおりに機能します。
class Filters @Inject()(enabledFilters: EnabledFilters, corsFilter: CORSFilter)
extends DefaultHttpFilters(enabledFilters.filters :+ corsFilter: _*)
デフォルトフィルタのテスト
いくつかのフィルターが有効になっているため、すべてのテストが合格し、要求が有効であることを確認するために機能テストを少し変更する必要があります。たとえば、 Host
HTTPヘッダーが localhost
に設定されていない要求は AllowedHostsFilter を渡さず、代わりに 400 Forbidden 応答を返します。
AllowedHostsFilterを使用したテスト
AllowedHostsFilterフィルターが自動的に追加されるため、機能テストでは、Host HTTPヘッダーが追加されている必要があります。
FakeRequest
または Helpers.fakeRequest
を使用している場合は、Host
HTTPヘッダーが自動的に追加されます。 play.mvc.Http.RequestBuilder
を使用している場合は、ヘッダを手動で追加するために独自の行を追加する必要があります。
RequestBuilder request = new RequestBuilder()
.method(GET)
.header(HeaderNames.HOST, "localhost")
.uri("/xx/Kiwi");
CSRFFilterによるテスト
CSRFFilterフィルタが自動的に追加されるので、 CSRF.formField
を含むTwirlテンプレートをレンダリングするテスト。
@(userForm: Form[UserData])(implicit request: RequestHeader, m: Messages)
<h1>user form</h1>
@request.flash.get("success").getOrElse("")
@helper.form(action = routes.UserController.userPost()) {
@helper.CSRF.formField
@helper.inputText(userForm("name"))
@helper.inputText(userForm("age"))
<input type="submit" value="submit"/>
}
要求にCSRFトークンを含める必要があります。 Scala APIでは、これは play.api.test.CSRFTokenHelper._
をインポートすることによって実行されます。これは play.api.test.FakeRequest
を withCSRFToken
メソッドで埋められます:
import play.api.test.CSRFTokenHelper._
class UserControllerSpec extends PlaySpec with GuiceOneAppPerTest {
"UserController GET" should {
"render the index page from the application" in {
val controller = app.injector.instanceOf[UserController]
val request = FakeRequest().withCSRFToken
val result = controller.userGet().apply(request)
status(result) mustBe OK
contentType(result) mustBe Some("text/html")
}
}
}
Java APIでは、これは play.mvc.Http.RequestBuilder
インスタンスで CSRFTokenHelper.addCSRFToken
を呼び出すことによって行われます。
requestBuilder = CSRFTokenHelper.addCSRFToken(requestBuilder);
デフォルトのフィルタを無効にする
デフォルトのフィルタを無効にする最も簡単な方法は、 application.conf
に手動でフィルタのリストを設定することです。
play.filters.enabled = []
これは、デフォルトのフィルタを使用したくない機能テストがある場合に便利です。
すべてのフィルタクラスを削除する場合は、 disablePlugins
メカニズムを使用してフィルタクラスを無効にすることができます。
lazy val root = project.in(file(".")).enablePlugins(PlayScala).disablePlugins(PlayFilters)
あるいは EnabledFilters
で置換
play.http.filters = play.api.http.NoHttpFilters
GuiceApplicationBuilder
を含む機能テストを作成していて、デフォルトのフィルタを無効にしたい場合は、 configure
を使用してフィルタをすべて無効にすることができます。
GuiceApplicationBuilder().configure("play.http.filters" -> "play.api.http.NoHttpFilters")
コンパイル時のデフォルトフィルタ
コンパイル時依存関係注入を使用している場合、デフォルトのフィルタは実行時ではなくコンパイル時に解決されます。
これは、 BuiltInComponents
トレイトに httpFilters
メソッドが含まれていて、抽象化されたままであることを意味します。
trait BuiltInComponents {
/** A user defined list of filters that is appended to the default filters */
def httpFilters: Seq[EssentialFilter]
}
フィルタのデフォルトリストは play.filters.HttpFiltersComponents
で定義されています:
trait HttpFiltersComponents
extends CSRFComponents
with SecurityHeadersComponents
with AllowedHostsComponents {
def httpFilters: Seq[EssentialFilter] = Seq(csrfFilter, securityHeadersFilter, allowedHostsFilter)
}
ほとんどの場合、 HttpFiltersComponents
をミックスして独自のフィルタを追加する必要があります:
class MyComponents(context: ApplicationLoader.Context)
extends BuiltInComponentsFromContext(context)
with play.filters.HttpFiltersComponents {
lazy val loggingFilter = new LoggingFilter()
override def httpFilters = {
super.httpFilters :+ loggingFilter
}
}
リストから要素をフィルタリングする場合は、次の操作を実行できます。
class MyComponents(context: ApplicationLoader.Context)
extends BuiltInComponentsFromContext(context)
with play.filters.HttpFiltersComponents {
override def httpFilters = {
super.httpFilters.filterNot(_.getClass == classOf[CSRFFilter])
}
}
コンパイル時デフォルトフィルタの無効化
デフォルトのフィルタを無効にするには、 play.api.NoHttpFiltersComponents
をミックスインします:
class MyComponents(context: ApplicationLoader.Context)
extends BuiltInComponentsFromContext(context)
with NoHttpFiltersComponents
with AssetsComponents {
lazy val homeController = new HomeController(controllerComponents)
lazy val router = new Routes(httpErrorHandler, homeController, assets)
}
JWTサポート
Play の Cookie エンコーディングが JSON Webトークン(JWT) を使用するように切り替わりました。 JWTには、HMAC-SHA-256による自動署名や、セッションクッキーが指定された時間枠外で再利用できないことを保証する自動「前回」および「期限切れ」日付チェックのサポートなど、多くの利点があります。
詳細は、「セッションCookieの設定」ページを参照してください。
フォールバッククッキーのサポート
PlayのCookieエンコーディングは、JWTでエンコードされたCookieを読み込み、JWTの解析が失敗した場合にURLでエンコードされたCookieを読み取ろうとする「フォールバック」Cookieエンコードメカニズムを使用しているため、既存のセッションCookieをJWTに安全に移行できます。この機能は FallbackCookieDataCodec
トレイトにあり、 DefaultSessionCookieBaker
と DefaultFlashCookieBaker
を利用しています。
レガシーサポート
JWTでエンコードされたクッキーを使用することはシームレスでなければなりませんが、必要に応じて application.conf
ファイルの play.api.mvc.LegacyCookiesModule
に切り替えることでURLエンコードされたクッキーエンコーディングに戻すことができます:
play.modules.disabled+="play.api.mvc.CookiesModule"
play.modules.enabled+="play.api.mvc.LegacyCookiesModule"
カスタムCookieBakers
カスタム Cookie が CookieBaker[T]
トレイトを使用して Play で使用されている場合は、カスタム Cookie ベーカーに必要なエンコーディングの種類を指定する必要があります。
The encode
and decode
methods that Map[String, String]
to and from the format found in the browser have been extracted into CookieDataCodec
。 FallbackCookieDataCodec
、 JWTCookieDataCodec
、または UrlEncodedCookieDataCodec
の3つの実装があります。それぞれHMAC、JWT、または「JWTの書き込みコードまたはJWTの読み取り」コーデックでURLエンコードされています。
また、JWTConfigurationParser
を使用して構成へのパスを使用して JWTConfiguration
case class を提供するか、またはデフォルトの JWTConfiguration()
を使用する必要があります。
@Singleton
class UserInfoCookieBaker @Inject()(service: UserInfoService,
val secretConfiguration: SecretConfiguration)
extends CookieBaker[UserInfo] with JWTCookieDataCodec {
override val COOKIE_NAME: String = "userInfo"
override val isSigned = true
override def emptyCookie: UserInfo = new UserInfo()
override protected def serialize(userInfo: UserInfo): Map[String, String] = service.encrypt(userInfo)
override protected def deserialize(data: Map[String, String]): UserInfo = service.decrypt(data)
override val path: String = "/"
override val jwtConfiguration: JWTConfiguration = JWTConfigurationParser()
}
非推奨のFuturesメソッド
次の play.libs.concurrent.Futures
静的メソッドは廃止予定です:
timeout(A value, long amount, TimeUnit unit)
timeout(final long delay, final TimeUnit unit)
delayed(Supplier<A> supplier, long delay, TimeUnit unit, Executor executor)
依存関係が挿入された Futures
のインスタンスを代わりに使用する必要があります。
class MyClass {
@Inject
public MyClass(play.libs.concurrent.Futures futures) {
this.futures = futures;
}
CompletionStage<Double> callWithOneSecondTimeout() {
return futures.timeout(computePIAsynchronously(), Duration.ofSeconds(1));
}
}
更新されたライブラリ
Netty 4.1
Nettyは バージョン4.1 にアップグレードされました。これは主に、バージョン4.0が スタンドアローンモジュールへのplay-wsの移行 によって網羅されていたために可能でした。したがって、 Netty Server と Netty 4.0に依存するライブラリを使用している場合は、ライブラリの新しいバージョンにアップグレードするか、 Akka Server の使用を開始することをお勧めします。
何らかの理由でNettyクラスを直接使用している場合は、 コードをこの新しいバージョンに適合させる 必要があります。
FluentLeniumとSelenium
FluentLeniumライブラリはバージョン 3.2.0 にアップデートされ、Selenium はバージョン 3.3.1 にアップデートされました(ここで変更履歴をご覧ください)。以前に Selenium の WebDriver API を使用していた場合は、何もするべきではありません。詳細については、 この アナウンスを確認してください。
FluentLenium ライブラリを使用していた場合は、テストを再開するためにいくつかの構文を変更する必要があります。あなたのコードを変更する方法の詳細については、FluentLeniumの 移行ガイド を参照してください。
HikariCP
HikariCP が更新され、新しい設定が導入されました: initializationFailTimeout
。この新しい構成は、現在廃止されている initializationFailFast
の代わりに使用する必要があります。この新しい設定の使い方を理解するには、 HikariCPの変更ログ と initializationFailTimeout
のドキュメント を参照してください。
その他の構成の変更
いくつかの設定変更があります。通常、古い設定パスは動作しますが、使用すると、実行時に非推奨警告が出力されます。変更されたキーの概要を以下に示します。
|古いキー | 新しいキー |
|-------+----------+
|play.crypto.secret | play.http.secret.key|
|play.crypto.provider | play.http.secret.provider|
|play.websocket.buffer.limit | play.server.websocket.frame.maxLength|