ドキュメント

§Play 2.7 移行ガイド

これは、Play 2.6からPlay 2.7に移行するためのガイドです。Playの以前のバージョンから移行する必要がある場合は、最初にPlay 2.6移行ガイドに従う必要があります。

§移行方法

sbtでPlayプロジェクトを読み込み/実行する前に、sbtビルドを更新するには、次の手順を実行する必要があります。

§Playのアップグレード

Playをアップグレードするには、`project/plugins.sbt`のPlayバージョン番号を更新します

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.x")

`2.7.x`の「x」は、使用するPlayのマイナーバージョンです。たとえば、`2.7.0`です。

§sbt 1.2.8へのアップグレード

Play 2.7はsbt 0.13シリーズをまだサポートしていますが、今後sbt 1.xを使用することをお勧めします。この新しいバージョンは積極的にメンテナンスおよびサポートされています。更新するには、`project/build.properties`を次のように変更します

sbt.version=1.2.8

これを書いている時点では、`1.2.8`はsbt 1.xファミリの最新バージョンです。より新しいバージョンも使用できる場合があります。Play 2.7.xのマイナーバージョンのリリースノートで詳細を確認してください。詳細については、sbtリリースのリストをご覧ください。

§APIの変更

既存のAPIを削除する前に廃止するというポリシーに従って、複数のAPIが変更されました。このセクションでは、これらの変更について詳しく説明します。

§廃止されたAPIが削除されました

以前のバージョンで廃止された多くのAPIは、Play 2.7で削除されました。まだ使用している場合は、Play 2.7にアップグレードする前に新しいAPIに移行することをお勧めします。JavadocとScaladocの両方には、通常、移行方法に関する適切なドキュメントがあります。詳細については、Play 2.6の移行ガイドを参照してください。

§StaticRoutesGeneratorが削除されました

2.6.0で廃止された`StaticRoutesGenerator`は削除されました。まだ使用している場合は、`build.sbt`ファイルから次のような行を削除する必要があるでしょう

routesGenerator := StaticRoutesGenerator

§Java `Http.Context`の変更

`play.mvc.Http.Context` APIで行われた変更を参照してください。これはJavaユーザーのみに関係します:Java `Http.Context`の変更

§Play WSの変更

Play 2.6では、Play-WSのほとんどを、独立したリリースサイクルを持つスタンドアロンプロジェクトに抽出しました。Play-WSには、Play自体にいくつかの変更が必要な重要なリリースがあります。

Play-WS 2.0は、グローバルな内部Cookieストアを持つAsync-Http-Clientの更新バージョンを提供します。サードパーティサービスへのリクエストでユーザーの機密Cookieを送信する場合、アプリケーションに影響を与える可能性があります。たとえば、Cookieストアはグローバルであるため、アプリケーションは同じホストにリクエストを行うときに、あるユーザーのCookieを別のユーザーのCookieと混同する可能性があります。キャッシュを有効または無効にするために使用できる新しい構成があります

# Enables global cache cookie store
play.ws.ahc.useCookieStore = true

デフォルトでは、キャッシュは無効になっています。これは、リダイレクトに自動的に従うなど、他の場所にも影響します。以前は、最初のリクエストのCookieが後続のリクエストで送信されていましたが、キャッシュが無効になっている場合はそうではありません。現在、リクエストごとにキャッシュを設定する方法はありません。

§Scala API

  1. `play.api.libs.ws.WSRequest.requestTimeout`は、`Option[Int]`ではなく`Option[Duration]`を返すようになりました。

§Java API

  1. `play.libs.ws.WSRequest.getUsername`は、`String`ではなく`Optional<String>`を返すようになりました。
  2. `play.libs.ws.WSRequest.getContentType` は、`String` ではなく `Optional<String>` を返すようになりました。
  3. `play.libs.ws.WSRequest.getPassword` は、`String` ではなく `Optional<String>` を返すようになりました。
  4. `play.libs.ws.WSRequest.getScheme` は、`WSScheme` ではなく `Optional<WSScheme>` を返すようになりました。
  5. `play.libs.ws.WSRequest.getCalculator` は、`WSSignatureCalculator` ではなく `Optional<WSSignatureCalculator>` を返すようになりました。
  6. `play.libs.ws.WSRequest.getRequestTimeout` は、`long` ではなく `Optional<Duration>` を返すようになりました。
  7. `play.libs.ws.WSRequest.getRequestTimeoutDuration` は、`play.libs.ws.WSRequest.getRequestTimeout` を使用するために削除されました。
  8. `play.libs.ws.WSRequest.getFollowRedirects` は、`boolean` ではなく `Optional<Boolean>` を返すようになりました。

Java APIを改善するために、いくつかの新しいメソッドも追加されました

新しいメソッド `play.libs.ws.WSResponse.getBodyAsSource` は、レスポンスボディを `Source<ByteString, ?>` に変換します。例えば

wsClient.url("https://play.dokyumento.jp")
    .stream() // this returns a CompletionStage<StandaloneWSResponse>
    .thenApply(StandaloneWSResponse::getBodyAsSource);

Java APIを改善するために追加されたその他のメソッド

  1. `play.libs.ws.WSRequest.getBody` は、そのリクエストに設定されたボディを返します。`play.libs.ws.WSRequestFilter` を実装する場合に役立ちます
  2. `play.libs.ws.WSRequest.getMethod` は、そのリクエストに設定されたメソッドを返します。
  3. `play.libs.ws.WSRequest.getAuth` は、`WSAuth` を返します。
  4. `play.libs.ws.WSRequest.setAuth` は、そのリクエストの `WSAuth` を設定します。
  5. `play.libs.ws.WSResponse.getUri` は、そのレスポンスの `URI` を取得します。

§BodyParsers APIの整合性

ボディパーサーのAPIは、バッファ長を定義するために`Integer`と`Long`を混在させて使用しており、値のオーバーフローにつながる可能性がありました。構成は、`Long`を使用するように統一されました。つまり、たとえば`play.api.mvc.PlayBodyParsers.DefaultMaxTextLength`に依存している場合は、`Long`を使用する必要があります。そのため、`play.api.http.ParserConfiguration.maxMemoryBuffer`も`Long`になりました。

§パーサーの`maxMemoryBuffer`制限

一部のペイロードは、解析時にメモリ内で展開されます。そのため、メモリ表現は、ワイヤから読み取られたプレーンテキスト表現よりも多くのスペースを占有します。JSONはこのような形式の1つです。サービス拒否を引き起こす可能性のあるメモリ不足エラーを防ぐために、ボディの解析とフォームのバインディングは`play.http.parser.maxMemoryBuffer`設定を尊重する必要があります。

特定のケースでは、`maxMemoryBuffer`を緩和することも可能です。JSON表現と展開された表現のサイズが異なり、異なる制限を使用する必要がある場合があります。次のように、カスタマイズされた制限を使用してフォームバインディングを使用できます

class MyController @Inject()(cc: ControllerComponents) {

  // This will be the action that handles our form post
  def myMethod = Action { implicit request: Request[_] =>
    // create a new formBinding instance with increased limit 
    val defaultFormBinding: FormBinding = cc.parsers.formBinding(300*1024) // limit to 300KiB
    form.bindFromRequest()(request, formBinding)
    ...
  }

}

コントローラーには、常に`play.http.parser.maxMemoryBuffer`を尊重するように構築された`FormBinding`インスタンスがあります。コントローラー外のコードからフォームを使用する場合は、暗黙的な`FormBinding`を提供する必要がある場合があります。たとえば、ユニットテストを作成する場合は、テストには十分なハードコードされた制限を使用する`play.api.data.FormBinding.Implicits._`で提供される`FormBinding`を使用できます。スコープに暗黙的を追加します

`scala import play.api.data.FormBinding.Implicits._

§`FilePart`と`FileInfo`に追加された新しいフィールドとメソッド

`Scala``Java`の`FilePart`クラスには、`multipart/form-data`エンコーディングを介してアップロードされたファイルのファイルサイズとディスポジションタイプを提供する2つの新しいフィールド/メソッドがあります

Scala の FileInfo クラスにも、dispositionType フィールドが追加されました。

Scala で FilePart または FileInfo を含む case 文を使用している場合は、これらの新しいフィールドを含めるように文を更新する必要があります。そうしないと、コンパイルエラーが発生します。

FilePart
case FilePart(key, filename, contentType, file, fileSize, dispositionType) => ...
// Or if you don't use these new fields:
case FilePart(key, filename, contentType, file, _, _) => ...
FileInfo
case FileInfo(partName, filename, contentType, dispositionType) => ...
// Or if you don't use these new fields:
case FileInfo(partName, filename, contentType, _) => ...

§カスタムボディパーサーを使用する場合、アップロードされたファイルのサイズを FilePart に渡す

Play Scala または Play Javamultipart/form-data エンコーディングを使用してファイルをアップロードする場合、FilePart は、Scala API の fileSize と Java API の getFileSize() を介してアップロードされたファイルのサイズを公開するようになりました。
ファイルアップロードにカスタムボディパーサーを使用する場合は、生成された FilePart インスタンスにファイルサイズを自分で渡す必要があります。そうしないと、ファイルサイズは設定されず、デフォルトで -1 になります。更新されたカスタムマルチパートファイルパートボディパーサーの例を参照してください。これらの例では、処理されたバイト数(アップロードされたファイルの)の count が、作成された FilePart に渡されます。

§Java の FilePart は、アップロードされたファイルの TemporaryFile を公開する

デフォルトでは、multipart/form-data エンコーディングを使用した ファイルのアップロード は、一時ファイルシステムにファイルを保存することに依存する TemporaryFile API を使用します。
ただし、Play 2.6 までは、その TemporaryFile に直接アクセスすることはできず、それが裏付けとなっている File にのみアクセスできました。

Http.MultipartFormData<File> body = request.body().asMultipartFormData();
Http.MultipartFormData.FilePart<File> picture = body.getFile("picture");
if (picture != null) {
    File file = picture.getFile();
}

上記で使用されている getFile() メソッドは非推奨になり、代わりに getRef() を使用する必要があります。これは、いくつかの便利なメソッド を備えた TemporaryFile インスタンスを提供します。
Play 2.7 以降、上記のコードは次のようにリファクタリングする必要があります。

Http.MultipartFormData<TemporaryFile> body = request.body().asMultipartFormData();
Http.MultipartFormData.FilePart<TemporaryFile> picture = body.getFile("picture");
if (picture != null) {
    TemporaryFile tempFile = picture.getRef();
    File file = tempFile.path().toFile();
}

§copyTo を追加し、TemporaryFile の move メソッドの名前を変更しました

Play 2.5 までは、moveTo メソッドは実際にはファイルのコピーを宛先に作成し、ソースを削除していました。Play 2.6 では、特定の条件に応じてファイルがアトミックに移動されるという微妙な変更がありました。このような場合、ソースと宛先の両方が同じ inode を使用することになります。
これに関する API をより明確にするために、ソースファイルの inode を共有しないコピーを常に作成する copyTo メソッドが追加されました。

Play 2.7 のもう1つの変更点は、ファイルを移動する TemporaryFile のメソッドの名前が変更されたことです。

非推奨のメソッド 新しいメソッド
moveTo(...) moveFileTo(...)
atomicMoveWithFallback(...) atomicMoveFileWithFallback(...)

これらの新しいメソッドは、TemporaryFile の代わりに Path を返すようになりました。これらのメソッドから TemporaryFile を返すのは、最初から間違いでした。なぜなら、誰かが、そのような返されたファイルが実際のテンポラリファイルであり、最終的に Play のテンポラリファイルクリーンアップ機能によって自動的に削除されると誤解する可能性があるからです。しかし、これは真実ではありません。
これらのメソッドは、ファイルを Play の内部一時フォルダー(アップロードされたファイルが最初に保存される場所)から移動するときに使用することを目的としているため、最終的には移動された宛先ファイルをどうするか(そして、いつ、どのように削除するか)は開発者の責任です。戻り値の型を変更することで、それが明確になります。

§Guice の互換性に関する変更

Guice がバージョン 4.2.2 にアップグレードされました(4.2.14.2.0 リリースノート も参照してください)。これにより、以下の破壊的変更が発生します。

§静的 Logger シングルトンは非推奨

Java の play.Logger のほとんどの `static` メソッドと、Scala の `play.api.Logger` シングルトンオブジェクトのほぼすべてのメソッドは非推奨になりました。これらのシングルトンは、`application` ロガーに書き込みました。これは、`logback.xml` で次のように参照されます。

<logger name="application" level="DEBUG" />

ロギング設定の変更が懸念される場合は、`Logger("application")` (Scala) または `Logger.of("application")` (Java) を使用して、独自のシングルトン "application" ロガーを定義するのが最も簡単な移行方法です。このロガーに送信されたすべてのログは、Play シングルトンロガーとまったく同じように機能します。一般的にこのアプローチは推奨しませんが、最終的にはあなた次第です。 Play と Logback は、ロガーに特定の命名スキームを使用することを強制しません.

簡単なコード変更とロギング設定の変更に抵抗がない場合は、代わりに、クラス名と一致する名前で、クラスごとに新しいロガーを作成することをお勧めします。これにより、クラスまたはパッケージごとに異なるログレベルを設定できます。たとえば、すべての `com.example.models` のログレベルを情報レベルに設定するには、`logback.xml` で次のように設定します.

<logger name="com.example.models" level="INFO" />

各クラスでロガーを定義するには、次のように定義できます。

Java
import play.Logger;
private static final Logger.ALogger logger = Logger.of(YourClass.class);
Scala
import play.api.Logger
private val logger = Logger(classOf[YourClass])

Scala の場合、Play は `val logger: Logger` を自動的に追加するためにクラスまたはトレイトに混在できる `play.api.Logging` トレイトも提供します.

import play.api.Logging

class MyClass extends Logging {
  // `logger` is automaticaly defined by the `Logging` trait:
  logger.info("hello!")
}

もちろん、SLF4J を直接使用することもできます.

Java
private static final Logger logger = LoggerFactory.getLogger(YourClass.class);
Scala
private val logger = LoggerFactory.getLogger(classOf[YourClass])

Java で SLF4J を直接使用するときに、より簡潔なソリューションが必要な場合は、Project Lombok の `@Slf4j` アノテーション を検討することもできます.

**注**: SLF4J のロギングインターフェースである `org.slf4j.Logger` は、まだ 遅延評価のためのパラメーターとしてラムダ式を受け入れるロギングメソッドを提供していません. `play.Logger` と `play.api.Logger` は、ほとんどの場合 `org.slf4j.Logger` の単純なラッパーですが、そのようなメソッドを提供します.

`application` ロガーの使用を中止したら、それを参照する `logback.xml` の `logger` エントリを削除できます.

<logger name="application" level="DEBUG" />

§アプリケーションローダー API の変更

カスタム `ApplicationLoader` を使用している場合、テストの実行時にこのローダーのインスタンスを手動で作成している可能性があります。そのためには、まず `ApplicationLoader.Context` のインスタンスを作成する必要があります。例:

val env = Environment.simple()
val context = ApplicationLoader.Context(
  environment = env,
  sourceMapper = None,
  webCommands = new DefaultWebCommands(),
  initialConfiguration = Configuration.load(env),
  lifecycle = new DefaultApplicationLifecycle()
)
val loader = new MyApplicationLoader()
val application = loader.load(context)

ただし、上記のコードで使用されている `ApplicationLoader.Context` apply メソッドは非推奨になり、`webCommands` が null でない場合は例外をスローします. 新しいコードは次のとおりです.

val env = Environment.simple()
val context = ApplicationLoader.Context.create(env)
val loader = new GreetingApplicationLoader()
val application = loader.load(context)

§JPA の削除と非推奨

Play 2.6 ですでに非推奨になっていたクラス `play.db.jpa.JPA` は、ついに削除されました. まだの場合は、Play 2.6 JPA 移行に関する注意事項 を参照してください.

この Play リリースでは、さらに多くの JPA 関連のメソッドとアノテーションが非推奨になりました.

Play 2.6 JPA 移行に関する注意事項ですでに述べたように、これらの非推奨のメソッドとアノテーションの代わりに、play.db.jpa.JPAApi の使用 で説明されているように、`JPAApi` 注入インスタンスを使用してください.

§Router#withPrefix は常にプレフィックスを追加する必要があります

以前は、`router.withPrefix(prefix)` はルーターにプレフィックスを追加することを目的としていましたが、「レガシー実装」が既存のプレフィックスを更新することを許可していました. Play の `SimpleRouter` や他のクラスはこの動作に従っていました. 現在、すべての実装がプレフィックスを追加するように更新されたため、`router.withPrefix(prefix)` は常に `s"$prefix/$path"` を `router` が `path` をルーティングするのと同じ方法でルーティングするルーターを返す必要があります.

デフォルトでは、ルーターにはプレフィックスが付いていないため、これは、すでに `withPrefix` によって返されたルーターで `withPrefix` を呼び出している場合にのみ動作の変更を引き起こします. ルーターにすでに設定されているプレフィックスを置き換えるには、プレフィックス付きバージョンではなく、元のプレフィックスなしルーターで `withPrefix` を呼び出す必要があります.

§実行フック

`RunHook.afterStarted()` は、パラメーターとして `InetSocketAddress` を受け取らなくなりました.

§すべての Java フォーム `validate` メソッドは、クラスレベルの制約に移行する必要があります

Java フォームの「古い」`validate` メソッドは、もはや実行されません.
Play 2.6 移行ガイド で発表されたように、そのような `validate` メソッドを クラスレベルの制約 に移行する必要があります.

**重要**: Play 2.7 にアップグレードしても、`validate` メソッドを移行する必要があることを示すコンパイラの警告は表示されません(Play はリフレクションを介してそれらを実行したため).

§Java `Form`、`DynamicForm`、`FormFactory` のコンストラクターが変更されました

`play.data` 内の `Form`、`DynamicForm`、`FormFactory` クラスの `Validator` パラメーターを使用していたコンストラクターは、代わりに `ValidatorFactory` パラメーターを使用するようになりました.
それに加えて、これらのコンストラクターには `com.typesafe.config.Config` パラメーターも必要になりました.
例:`new Form(..., validator)` は `new Form(..., validatorFactory, config)` になります.
この変更は、`formFactory.form(SomeForm.class)` を使用する代わりに、コンストラクターを使用してフォームをインスタンス化する場合にのみ影響します。ほとんどの場合、テスト中です.

§Java Cache API `get` メソッドは、`getOptional` に代わって非推奨になりました

Java `cacheApi` の `getOptional` メソッドは、結果を `Optional` でラップして返します.

`play.cache.SyncCacheApi` の変更

非推奨のメソッド 新しいメソッド
<T> T get(String key) <T> Optional<T> getOptional(String key)

`play.cache.AsyncCacheApi` の変更

非推奨のメソッド 新しいメソッド
<T> CompletionStage<T> get(String key) <T> CompletionStage<Optional<T>> getOptional(String key)

§`Server.getHandlerFor` は `Server#getHandlerFor` に移動しました

`Server` トレイトの `getHandlerFor` メソッドは、リクエストのルーティング時に Play サーバーコードによって内部的に使用されていました. 削除され、`Server` オブジェクトの同じ名前のメソッドに置き換えられました.

§Java DI 非依存 Play `Module` API サポートが追加され、すべての組み込み Java `Module` の型が変更されました

Java で DI に依存しない Play の Module を作成できるようになりました。play.inject.Module を拡張することで、Java API を使用し、Java でコーディングされているため、より Java フレンドリーになります。さらに、既存の組み込み Java Module(例:play.inject.BuiltInModuleplay.libs.ws.ahc.AhcWSModule)は、Scala の play.api.inject.Module ではなく、Java の play.inject.Module を拡張するようになりました。

Java の play.inject.Module は Scala の play.api.inject.Module のサブクラスであるため、Module インスタンスは同じ方法で使用できます。ただし、インターフェースが少し異なります。

public class MyModule extends play.inject.Module {
    @Override
    public java.util.List<play.inject.Binding<?>> bindings(final play.Environment environment, final com.typesafe.config.Config config) {
        return java.util.Collections.singletonList(
            // Note: it is bindClass() but not bind()
            bindClass(MyApi.class).toProvider(MyApiProvider.class)
        );
    }
}

§play.mvc.Results.TODO は play.mvc.Controller.TODO に移動しました

Play のすべてのエラーページが更新され、CSPFilter が存在する場合、CSP nonce をレンダリングするようになりました。これは、エラーページテンプレートがリクエストをパラメータとして受け取る必要があることを意味します。2.6.x では、TODO フィールドは HTTP コンテキストを持つアクションではなく静的な結果としてレンダリングされていたため、コントローラ外で呼び出される可能性がありました。2.7.0 では、TODO フィールドは削除され、代わりに play.mvc.ControllerTODO(Http.Request request) メソッドが追加されました。

public abstract class Controller extends Results implements Status, HeaderNames {
    public static Result TODO(play.mvc.Http.Request request) {
        return status(NOT_IMPLEMENTED, views.html.defaultpages.todo.render(request.asScala()));
    }
}

§内部変更

Play の内部 API には多くの変更が加えられました。これらの API は内部的に使用され、通常の非推奨プロセスには従いません。Play の内部 API と直接統合しているユーザーのために、変更点が以下に記載されている場合があります。

§設定の変更

§play.allowGlobalApplication のデフォルト値は false になりました

Play 2.7.0 では、play.allowGlobalApplication = false がデフォルトで設定されています。これは、Play.current を呼び出すと例外がスローされることを意味します。これを true に設定すると、Play.current とその他の非推奨の静的ヘルパーが再び機能しますが、この機能は将来のバージョンで削除されることに注意してください。

今後、アプリケーションコンポーネントの静的インスタンスを使用する必要がある場合は、Guice を使用した 静的インジェクション を使用してそれらをインジェクトするか、アプリケーションローダーの起動時に静的フィールドを手動で設定できます。アプリケーションを同時実行しないように注意すれば(例:テスト中)、これらのアプローチは将来のバージョンの Play と互換性があります。

Play.current は、一部の非推奨 API によって引き続き呼び出されるため、そのような API を使用する場合、application.conf ファイルに次の行を追加する必要があります。

play.allowGlobalApplication = true

たとえば、組み込み Play と Scala Sird Routerplay.api.mvc.Action オブジェクトを使用する場合、グローバル状態にアクセスします。

import play.api.mvc._
import play.api.routing.sird._
import play.core.server._

// It can also be NettyServer
val server = AkkaHttpServer.fromRouter() {
  // `Action` in this case is the `Action` object which access global state
  case GET(p"/") => Action {
    Results.Ok(s"Hello World")
  }
}

上記の例では、前述のように play.allowGlobalApplication = true を設定するか、以下のように書き直す必要があります。

import play.api._
import play.api.mvc._
import play.api.routing.sird._
import play.core.server._

// It can also be NettyServer
val server = AkkaHttpServer.fromRouterWithComponents() { components: BuiltInComponents => {
    case GET(p"/") => components.defaultActionBuilder {
      Results.Ok(s"Hello World")
    }
  }
}

§HikariCP は即時失敗しなくなりました

Play 2.7 では、HikariCP の initializationFailTimeout のデフォルト値が -1 に変更されました。つまり、データベースが利用できない場合でもアプリケーションは起動します。initializationFailTimeout1 に設定することで、プールを即時失敗させるようにして、古い動作に戻すことができます。

アプリケーションがデータベースの Evolutions を使用している場合、適用する新しい進化があるかどうかを確認するために、アプリケーションの起動時に接続が要求されます。そのため、接続が必要になるため、データベースが利用できない場合、起動は失敗します。タイムアウトは connectionTimeout(デフォルトは 30 秒)によって定義されます。

詳細は SettingsJDBC を参照してください。

§CoordinatedShutdown play.akka.run-cs-from-phase 設定

設定 akka.coordinated-shutdown.exit-jvm はサポートされなくなりました。この設定が有効になっていると、Play は起動せず、エラーがログに記録されます。Play には、ほとんどのシナリオに適した akka.coordinated-shutdown.* のデフォルト値が付属しているため、それらをオーバーライドする必要はほとんどありません。

設定 play.akka.run-cs-from-phase はサポートされなくなり、追加してもアプリケーションのシャットダウンには影響しません。存在する場合、警告がログに記録されます。Play は現在、すべてのフェーズを実行して、ApplicationLifecycle に登録されているすべてのフックと coordinated shutdown に追加されたすべてのタスクが実行されるようにします。特定のフェーズから CoordinatedShutdown を実行する必要がある場合は、いつでも手動で実行できます。

import akka.actor.ActorSystem
import javax.inject.Inject

import akka.actor.CoordinatedShutdown
import akka.actor.CoordinatedShutdown.Reason

class Shutdown @Inject()(actorSystem: ActorSystem) {

  // Define your own reason to run the shutdown
  case object CustomShutdownReason extends Reason

  def shutdown() = {
    // Use a phase that is appropriated for your application
    val runFromPhase = Some(CoordinatedShutdown.PhaseBeforeClusterShutdown)
    val coordinatedShutdown = CoordinatedShutdown(actorSystem).run(CustomShutdownReason, runFromPhase)
  }
}

Java の場合:

import akka.actor.ActorSystem;
import akka.actor.CoordinatedShutdown;

import javax.inject.Inject;
import java.util.Optional;

class Shutdown {

    public static final CoordinatedShutdown.Reason customShutdownReason = new CustomShutdownReason();

    private final ActorSystem actorSystem;

    @Inject
    public Shutdown(ActorSystem actorSystem) {
        this.actorSystem = actorSystem;
    }

    public void shutdown() {
        // Use a phase that is appropriated for your application
        Optional<String> runFromPhase = Optional.of(CoordinatedShutdown.PhaseBeforeClusterShutdown());
        CoordinatedShutdown.get(actorSystem).run(customShutdownReason, runFromPhase);
    }

    public static class CustomShutdownReason implements CoordinatedShutdown.Reason {}
}

§アプリケーションシークレットの最小長のチェック

アプリケーションシークレット 設定 play.http.secret.key は、本番環境で最小長のチェックを受けます。キーが 15 文字以下の場合、警告がログに記録されます。キーが 8 文字以下の場合、エラーがスローされ、設定は無効になります。このエラーを解決するには、シークレットを head -c 32 /dev/urandom | base64 などの完全にランダムな入力の少なくとも 32 バイトに設定するか、アプリケーションシークレットジェネレータを使用して playGenerateSecret または playUpdateSecret を使用します。

アプリケーションシークレット は、Play セッション Cookie が有効であること、つまり攻撃者によって偽装されたのではなくサーバーによって生成されたことを確認するためのキーとして使用されます。ただし、シークレットは文字列のみを指定し、その文字列のエントロピーの量を決定するものではありません。とにかく、シークレットの長さを測定するだけで、シークレットのエントロピー量の上限を設定することができます。シークレットの長さが 8 文字の場合、エントロピーは最大 64 ビットであり、これは現代の標準では不十分です。

§play.filters.headers.contentSecurityPolicy は CSPFilter のために非推奨になりました

SecurityHeaders フィルタ には contentSecurityPolicy プロパティがありますが、これは 2.7.0 で非推奨になりました。contentSecurityPolicydefault-src 'self' から null に変更されました。デフォルト設定の null は、SecurityHeaders フィルタからの HTTP レスポンスに Content-Security-Policy ヘッダーが追加されないことを意味します。CSP 機能を有効にするには、新しい CSPFilter を使用してください.

play.filters.headers.contentSecurityPolicynull でない場合、警告が表示されます。 技術的には contentSecurityPolicy と新しい CSPFilter を同時にアクティブにすることはできますが、お勧めしません。

新しい CSPFilter は、 play.filters.enabled プロパティに追加することで有効にできます。

play.filters.enabled += play.filters.csp.CSPFilter

**注意**:コンテンツセキュリティポリシーを綿密にレビューして、ニーズを満たしていることを確認してください. 新しい `CSPFilter` は、`default-src 'self'` よりも特に寛容であり、Google Strict CSP 構成に基づいています。 CSP レポートコントローラ を使用した `report-only` 機能を使用して、ポリシー違反を確認できます。

詳細については、CSPFilter のドキュメントを参照してください。

Play 2.6 では、SameSite Cookie 属性は セッションとフラッシュに対してデフォルトで有効 になりました.
Play 2.7 以降では、CSRF Cookie と言語 Cookie についても同じことが当てはまります。 デフォルトでは、CSRF Cookie の SameSite 属性はセッション Cookie と同じ値になり、言語 Cookie はデフォルトで SameSite=Lax を使用します。
これは設定を使用して微調整できます。 例えば

play.filters.csrf.cookie.sameSite = null // no same-site for csrf cookie
play.i18n.langCookieSameSite = "strict" // strict same-site for language cookie

§デフォルトの変更

Play で使用されるデフォルト値の一部が変更され、アプリケーションに影響を与える可能性があります。 このセクションでは、デフォルトの変更について詳しく説明します。

§JavaScript のデフォルトのコンテンツタイプとしての application/javascript

application/javascript が、text/javascript に代わる JavaScript のデフォルトのコンテンツタイプになりました。 生成された <script> タグでは、type 属性も省略するようになりました。 type 属性の省略の詳細については、HTML 5 仕様 を参照してください。

§自己署名 HTTPS 証明書の変更

ルートフォルダに直接ではなく、target/dev-mode/generated.keystore の下に生成されるようになりました.

§text/plain コンテンツタイプのデフォルトの文字セットの変更

テキストおよび許容テキストボディパーサーは、以前のデフォルトの ISO-8859-1 に代わって、デフォルトの文字セットとして US-ASCII を使用するようになりました。

これは、いくつかの新しい HTTP 標準、特に「テキストメディアタイプのデフォルトの文字セットである ISO-8859-1 は削除されました。デフォルトは、メディアタイプの定義が示すものです」と述べている RFC 7231、付録 B のためです。 text/plain メディアタイプの定義は、US-ASCII を指定する RFC 6657、セクション 4 によって定義されています。 テキストおよび許容テキストボディパーサーはコンテンツタイプとして text/plain を使用するため、現在は適切にデフォルト設定されています。

§更新されたライブラリ

このセクションでは、依存関係に加えられた重要な更新を示します。

§Akka の更新

Play 2.7 は、Akka 2.5 シリーズの最新バージョンを使用しています。 Akka ライブラリのバージョンの混在は 許可されていません。 最新バージョンは、複数のバージョンの Akka アーティファクトが使用されていることを検出すると警告を記録します。 次のようなものが表示されます

Detected possible incompatible versions on the classpath. Please note that a given Akka version MUST be the same across all modules of Akka that you are using, e.g. if you use [2.5.19] all other modules that are released together MUST be of the same version. Make sure you're using a compatible set of libraries. Possibly conflicting versions [2.5.4, 2.5.19] in libraries [akka-actor:2.5.19, akka-remote:2.5.4]

この例では、修正は akka-remote を Play が使用しているのと同じバージョンに更新することです。例:

val AkkaVersion = "2.5.19" // should match the version used by Play

libraryDependencies += "com.typesafe.akka" %% "akka-remote" % AkkaVersion

アプリケーションが Play で使用されているバージョンよりも新しいバージョンを使用している場合は、build.sbt ファイルで Akka バージョンを更新 できます。

§HikariCP の更新

HikariCP は最新バージョンに更新され、最終的に設定 initializationFailFast が削除され、initializationFailTimeout に置き換えられました。 HikariCP changelog および initializationFailTimeout のドキュメント を参照して、この設定の使用方法を理解してください。

§Guava バージョンが 27.1-jre に更新されました

Play 2.6.x は Guava ライブラリのバージョン 23.0 を提供していました。 現在、最新のバージョンである 27.1-jre に更新されています. ライブラリには多くの変更が加えられました。完全な changelog は こちら を参照してください。

§specs2 のバージョンを 4.3.5 に更新

以前のバージョンは 3.8.x でした。多くの変更と改善が含まれているため、Specs2 の最新バージョンの リリースノート をお読みになることをお勧めします。使用されるバージョンでは、使用されている Mockito のバージョンが 2.18.x に更新されたため、こちらも更新しました。

§Jackson のバージョンを 2.9 に更新

Jackson のバージョンが 2.8 から 2.9 に更新されました。このバージョンのリリースノートは こちら です。互換性を維持したリリースであるため、アプリケーションに影響はないはずです。しかし、新機能に興味があるかもしれません。

§Hibernate Validator のバージョンを 6.0 に更新

Hibernate Validator がバージョン 6.0 に更新され、Bean Validation 2.0 と互換性を持つようになりました。新機能については こちら をご覧ください。または、新しいバージョンに関する 詳細なブログ記事 をお読みください。

注意: このバージョンは、プロジェクトで使用している他の Hibernate 依存関係と完全には互換性がない可能性があることに注意してください。たとえば、hibernate-jpamodelgen を使用している場合は、すべてが連携して動作するように最新バージョンを使用する必要があります。

// Visit https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen to see the list of versions available
libraryDependencies += "org.hibernate" % "hibernate-jpamodelgen" % "5.3.7.Final" % "provided"

§ライブラリの削除

デフォルトの Play ディストリビューションのサイズを小さくするために、いくつかのライブラリを削除しました。次のライブラリは Play 2.7 では依存関係ではなくなったため、使用する場合はビルドに手動で追加する必要があります。

§BoneCP の削除

BoneCP は削除されました。アプリケーションが BoneCP を使用するように設定されている場合は、デフォルトの JDBC 接続プールである HikariCP に切り替える必要があります。

play.db.pool = "default"  # Use the default connection pool provided by the platform (HikariCP)
play.db.pool = "hikaricp" # Use HikariCP

HikariCP を使用するようにプールを再設定する必要がある場合があります。たとえば、HikariCP の最大接続数を設定する場合は、次のようになります。

play.db.prototype.hikaricp.maximumPoolSize = 15

詳細は、JDBC 設定セクション を参照してください。

また、完全修飾クラス名を指定することで、play.api.db.ConnectionPool を実装する独自のプールを使用することもできます。

play.db.pool=your.own.ConnectionPool

§Apache Commons (commons-lang3 および commons-codec)

Play は、プロジェクトで commons-codeccommons-lang3 を使用していた場合に、内部的に使用していました。使用する場合は、build.sbt に追加する必要があります。

// Visit https://mvnrepository.com/artifact/commons-codec/commons-codec to see the list of versions available
libraryDependencies += "commons-codec" % "commons-codec" % "1.11"

そして、commons-lang3 の場合は次のようになります。

// Visit https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 to see the list of versions available
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.8.1"

§その他の重要な変更

§DEV モードで evolution スクリプトを適用する必要がある場合にアプリケーションが起動する

Play 2.6 までは、DEV モードでデータベースに evolution スクリプトを実行する必要がある場合、アプリケーションは起動時に中止されていました。そのため、ApplicationEvolutions に依存するモジュールは初期化さえされませんでした。これは、モジュールで ApplicationEvolutions に依存している場合、モジュールが初期化されるまでにすべての evolution スクリプトが正常に実行され、たとえば、evolution スクリプトによってテーブルやその他のデータベースオブジェクトが作成されていることに依存して、モジュール内からデータベースにデータを挿入できることを意味していました。クエリに必要なデータベースオブジェクトです。

しかし、Play 2.7 以降では、DEV モードでは、evolution スクリプトを適用する必要があるかどうかに関係なく、アプリケーション (およびすべてのモジュール) は *常に* 起動するようになりました。これは、evolution スクリプトが正常に実行され、モジュールが初期化される時点で特定のデータベース構造が利用可能であるという事実に *依存できない* ことを意味します。
そのため、ApplicationEvolutions.upToDate を追加しました。これは、evolution の適用プロセスが完了したかどうかを示します。このメソッドが true を返した場合にのみ、すべての evolution スクリプトが正常に実行されたことを確認できます。DEV モードで evolution スクリプトを適用または解決するたびに、アプリケーションは自動的に再起動し、すべてのモジュールを再初期化するため、upToDate は最終的に true を返します。

§Evolutions コメント構文

Play Evolutions は、SQL92 コメント構文を正しくサポートするようになりました。つまり、好きな場所で # の代わりに、行頭に -- を使用して evolution を記述できます。Evolutions API を使用して新しく生成された evolution は、すべての領域で SQL92 スタイルのコメント構文も使用するようになりました。ドキュメントもそれに応じて更新され、SQL92 スタイルが優先されるようになりましたが、古いコメントスタイルも完全にサポートされています。

§クエリ文字列パラメータのバインディング動作の変更

§パラメータ値が空の場合 (例: ?myparam=)

以下のタイプのクエリ文字列パラメータを定義するルート

そして、以下の型でラップされているもの

Play 2.6 までは、リクエストのクエリ文字列パラメータが空の場合 (例: ?myparam=)、このようなケースでは 400 Bad Request が返されていました。
これは、空の文字列から上記の型を解析できなかったためです (例: Scala では、"".toInt は例外を発生させます。他の上記のすべての型も、それぞれの解析メソッドで例外を発生させます)。

Play 2.7 以降では、不正なリクエストは発生しなくなりますが、代わりに None (Scala の Option の場合)、Optional.empty() (Java の Optional の場合)、または空のリストが、このようなクエリパラメータのアクションメソッドに渡されます。
デフォルト値が定義されている場合 (例: myparam: Option[Int] ?= Option(123))、もちろんそのデフォルト値が渡されます。

注意: 上記の型が OptionOptional、またはリストでラップされていない場合 (例: myparam: Int ?= 3)、デフォルト値の動作も変更されました。Play 2.7 より前は、デフォルト値を選択する代わりに 400 Bad Request が発生していました。

§パラメータがまったく存在しない場合

以下の型でラップされたクエリ文字列パラメータにデフォルト値を定義するルート

は、リクエストのクエリ文字列パラメータがまったく存在しない場合、そのデフォルト値をアクションメソッドに渡していませんでした。代わりに、NoneOptional.empty()、または空のリストが渡されました。

Play 2.7 以降では、このような存在しないクエリパラメータに対して、デフォルト値がアクションメソッドに渡されるようになりました。

§multipart/form-data ファイルアップロードの変更

Play 2.6 までは、multipart/form-data エンコーディングを介して空のファイルをアップロードすることは、空でないファイルをアップロードすることと同じように扱われていました。しかし、明らかな理由から、空のファイルをアップロードすることはあまり意味がありません。そのため、Play 2.7 以降では、アップロードされた空のファイルは、ファイルがまったくアップロードされなかったのと同じように扱われます。
したがって、Scala API または Java API を介してアップロードされたファイルを取得する場合、ファイルが空になることはありません。

注意: multipart/form-data ファイルアップロードパートの filename ヘッダーが空の場合、ファイル自体が空でない場合でも、同じロジックが適用されます。

§Twirl 構文解析の改善

Twirl テンプレートの解析を改善するために、これまで有効だったコードがサポートされなくなりました。詳細については、この問題 を参照してください。

次: Java Http.Context の変更


このドキュメントに誤りを見つけましたか? このページのソースコードは こちら にあります。ドキュメントガイドライン を読んだ後、プルリクエストを送信してください。質問やアドバイスがありましたら、コミュニティフォーラム にアクセスして、コミュニティとの会話を始めてください。