Play 2.4移行ガイド【翻訳】

https://www.playframework.com/documentation/2.6.x/Migration24 を google翻訳した

----

# Play 2.4移行ガイド

これは、Play 2.3からPlay 2.4に移行するためのガイドです。以前のバージョンのPlayから移行する必要がある場合は、まず [Play 2.3移行ガイド](https://playframework.com/documentation/2.6.x/Migration23)に従わなければなりません。

## Java 8のサポート

Java 6とJava 7のサポートが廃止され、Play 2.4にJava 8が必要になりました。この決定は、[Java 7が2015年4月に廃止された](https://www.java.com/ja/download/faq/java_7.xml)に基づいて行われました。また、Java 8ではクリーンなAPIが可能になり、関数型プログラミングのサポートが強化されています。Java 6/7でPlay 2.4を使用しようとすると、次のようなエラーが表示されます。

```java
java.lang.UnsupportedClassVersionError: play/runsupport/classloader/ApplicationClassLoaderProvider : Unsupported major.minor version 52.0
```

[java.lang.UnsupportedClassVersionError](https://docs.oracle.com/javase/8/docs/api/java/lang/UnsupportedClassVersionError.html)は、Javaクラス・ファイルをJavaの古いバージョンでコンパイルされたクラスファイルはサポートされていません。

> **注：** Scala 2.10は、インターフェース上の静的メソッドのようなすべてのJava 8言語機能を完全にサポートしていません。プロジェクトにJava 8に含まれるこれらの新機能を使用するJavaコードがある場合は、Scala 2.11.6以降を使用するようにアップグレードしてください。プロジェクトに `scalaVersion`を設定する方法については、[sbt docs](http://www.scala-sbt.org/0.13/docs/Howto-Scala.html)を参照してください。

##ビルドの変更

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

### Playアップグレード

playをアップグレードするには、 `project/plugins.sbt` のPlayバージョン番号を更新してください：

```scala
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.0") // Set to latest version of Play 2.4
```

### sbt upgrade

Play 2.4では最低0.13.8のsbtが必要です。`project/build.properties`を次のように更新してください：

```scala
sbt.version=0.13.8
```

### 別のモジュールでのSpecs2のサポート

以前にPlayのspecs2サポートを使用していた場合は、そのプロジェクトへの依存関係を明示的に追加する必要があります。さらに、specs2は `scalaz-stream`を必要とします。これは、mavenの中央リポジトリやデフォルトで使用する他のリポジトリでは利用できません。したがって、` scalaz-stream`リポジトリをリゾルバとして追加する必要があります：

```scala
libraryDependencies += specs2 % Test
```


.scala ビルドファイルを使用している場合は、次のインポートを追加する必要があります。 `import play.sbt.PlayImport._`

### 別のモジュールでデータベースの進化をサポート

Play JDBCとJPAサポートの両方に含まれていた [データベースのEvolutions](https://playframework.com/documentation/2.6.x/Evolutions) のサポート。 それはもはや事実ではない。したがって、evolutionsを使用している場合は、プロジェクトのビルドで明示的な依存関係を `evolutions` に追加する必要があります：

```scala
libraryDependencies += evolutions
```

一方、evolutionsを使用していない場合、 `application.conf` から ` evolutionplugin = disabled` を安全に削除することができます。

設定キーが変更されたので、 `evolutionplugin = disabled` の代わりに ` play.evolutions.enabled = false` を使う必要があります( [Evolutions configuration](https://playframework.com/documentation/2.6.x/Evolutions＃Evolutions-configuration) を参照)

Play Slickモジュールを使用している場合(Evolutionsの有無にかかわらず)、状況はかなり変わりますので、[Play Slick移行ガイド](https://playframework.com/documentation/2.6.x/PlaySlickMigrationGuide)を必ずお読みください。

### IDE：EclipseとIntelliJ IDEA

Playにはもうsbteclipseプラグインまたはsbt-ideaプラグインが含まれていないため、ユーザーはPlayとは独立してIDEサポートをアップグレードできます。

Eclipseのサポートは、プラグインをインポートするための余分な行を1つでも設定することができます。詳細は、[IDE連携ドキュメント](https://playframework.com/documentation/2.6.x/IDE)を参照してください。

IntelliJは今ではsbtプロジェクトをネイティブにインポートできるようになりました。その代わりにIntelliJを使用することをお勧めします。代わりに、sbt-ideaプラグインを手動でインストールして使用することもできますが、ここには指示があります( https://github.com/mpeltonen/sbt-idea )。

### Play SBTプラグインAPI

SBTプラグインのすべてのクラスは、 `play.sbt`パッケージに入っています。これは、` .scala`ファイルを使ってビルドを構成する場合に特に関係します。play.sbt.PlayImportから識別子をインポートして、提供された構成要素を再生する必要があります。

#### `playWatchService`の名前が変更されました

SBT設定キー `playWatchService` の名前が ` fileWatchService` に変更されました。

対応するクラスも変更されました。2秒ごとにポーリングするようにFileWatchServiceを設定するには、次のように使用します。

```scala
PlayKeys.fileWatchService := play.runsupport.FileWatchService.sbt(2000)
```

### Play Slickの依存関係

Play Slickモジュールは、Slick 3.0をサポートするために大きな改訂を経ています。スムーズなアップグレードのためには、 [Play Slick移行ガイド](https://playframework.com/documentation/2.6.x/PlaySlickMigrationGuide) をお読みください。

### Ebeanの依存関係

Ebeanは外部プロジェクトに引き出され、Playのライフサイクルとは独立したライフサイクルを持つことができます。Ebeanのバイトコード拡張機能も、Play sbtプラグインから独自のプラグインに抽出されています。

Ebeanを使用する既存のPlayプロジェクトを移行して新しい外部Ebeanプラグインを使用するには、 `build.sbt`の` libraryDependencies`から `javaEbean`を削除し、` project/plugins.sbt` に以下を追加してください：

```scala
addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "1.0.0")
```

その後、あなたのプロジェクトにEbeanプラグインを有効にします：

```scala
lazy val myProject = (project in file("."))
  .enablePlugins(PlayJava, PlayEbean)
```

最後に、コンマで区切られた文字列ではなく、Ebeanマッピングされたクラスをリストとして設定します(まだサポートされていますが、推奨されていません)。

```
ebean.default = ["models.*"]
ebean.orders = ["models.Order", "models.OrderItem"]
```

さらに、Ebeanは4.5.xにアップグレードされました。これは、以前に追加されたPlayのいくつかの機能(Modelクラスを含む)を引き出します。その結果、 `Model` クラスのPlayは廃止され、 ` com.avaje.ebean.Model` が使用されました。

### バイトコードエンハンスメント

Javaプロパティのゲッタとセッタを生成する [Playのバイトコード拡張](https://playframework.com/documentation/2.6.x/PlayEnhancer) は、独自のライフサイクルを持つ独立して管理されたプロジェクトにPlayのコアから抜け出しました。これを有効にするには、 `project/plugins.sbt` ファイルに以下を追加します：

```scala
addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0")
```

## 依存性注入

Playは今、Guiceによって提供された依存性注入が使用されます。これはPlayからグローバルな状態を取り除くという長期的な戦略の一部です。これは、Play 3.0リリースで完了することを希望しています。グローバル状態に依存するアプリケーションをすべてグローバル状態フリーに移行することは大きな仕事です。一度に完了すると非常に混乱する可能性があります。この理由から、Playで取ってきたアプローチは、複数のリリースに渡って変更を分散することで、コードを徐々に移行させ、グローバルな状態に依存しないようにしました。

実際のところ、私たちはPlay 2.4で提供されるAPIがPlay 2.3とソース互換であることを保証しています。これは、多くの状況では、物事を行う2つの方法、グローバルな状態に依存する方法、およびそうでない方法があることを意味します。既存のAPIを使用して、それに関するドキュメントを参照したい場合、一般的に、Play 2.3のドキュメントはまだまだ関連しています。

Play 2.4への移行に進む前に、Playの依存関係注入に関するドキュメントを読むことが重要です。正面を決めるいくつかの決定があります。私たちは、Guiceの依存性注入の使用を提供し、奨励していますが、Scalaのコンパイル時依存性注入技術を含む他の多くの依存性注入ツールや手法も可能です。依存関係注入については [Java](https://playframework.com/documentation/2.6.x/JavaDependencyInjection) または [Scala](https://playframework.com/documentation/2.6.x/ScalaDependencyInjection) で読むことができます。

### ルーティング

依存性注入に関して最も破壊的な変化の1つは、現在2つのスタイルのルーターの生成をサポートしていることです。最初のものは既存のスタティックスタイルですが、これはPlay 2.3ルータとほとんど変わりません。これはScalaシングルトンオブジェクトであり、呼び出されるすべてのアクションがScalaシングルトンオブジェクトまたはJava静的メソッドであることを前提としています。2番目は依存関係注入ルータです。これは、そのコンストラクタで依存関係を宣言するクラスです。これらの2つのルータの違いを説明するには、次のルートファイルを検討してください。

```
GET   /               controllers.Application.index
POST  /save           controllers.Application.save
GET   /assets/*file   controllers.Assets.versioned(path = "/public", file: Asset)
```

スタティックルートジェネレータは、次のような非常に大雑把な(擬似コードの)ルータを生成します。

```scala
object Routes extends GeneratedRouter {
  def routes = {
    case ("GET", "/") => controllers.Application.index
    case ("POST", "/save") => controllers.Application.save
    case ("GET", "/assets/:file") => controllers.Assets.versioned("/public", file)
  }
}
```

一方、注入されたルートジェネレータは、次のような大雑把なルーターを生成します。

```scala
class Routes(application: controllers.Application, assets: controllers.Assets) extends GeneratedRouter {
  def routes = {
    case ("GET", "/") => application.index
    case ("POST", "/save") => application.save
    case ("GET", "/assets/:file") => assets.versioned("/public", file)
  }
}
```

デフォルトでは、スタティックルートジェネレータを使用します。すべてのJavaアクションを非静的メソッドに、またはScalaアクションをクラスに移行する準備ができていない場合は、これを使用する必要があります。ほとんどの場合、これは非常に簡単です.Javaでは `static` キーワードを削除する必要があり、Scalaでは `object` という単語を `class` に変更する必要があります。静的ルータは `@` 演算子をサポートしています。実行時の `Injector` からアクションを参照するように指示します。いくつかの Action が静的で、あるものがDIを利用する移行期にいる場合、これは便利です。

注入されたジェネレータに切り替える場合は、 `build.sbt` のビルド設定に以下を追加します：

```scala
routesGenerator := InjectedRoutesGenerator
```

デフォルトではPlayはGuiceを使用してこのルータの配線を自動的に処理しますが、使用しているDIアプローチによってはカスタマイズすることができます。

注入されたルートジェネレータは、ルート上の `@` 演算子もサポートしますが、コントローラが直接注入されるのではなく、コントローラにプレフィックスとして `@` を付けた場合、JSR 330 そのコントローラの「プロバイダ」が注入される。これは、たとえば、循環依存関係の問題を解消するため、または要求ごとに新しいアクションをインスタンス化する場合に使用できます。

さらに、Playはデフォルトでルートパッケージではなく `router`パッケージにルータを生成します。これは依存性注入を助けるためです。必要に応じて、ルートパッケージのクラスは通常は参照できないため、手動で作成またはバインドすることができます。

###依存性注入コンポーネント

Play 2.4では、コンポーネントの依存性注入バージョンを強制的に使用することはありませんが、それらのコンポーネントへの切り替えを開始することをお勧めします。次の表に、グローバル状態を使用する古い静的APIと、切り替えたい新しい注入APIを示します。

#### Scala

| Old API | New API | Comments |
| ------- | --------| -------- |
| [`Lang`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/i18n/Lang$.html) | [`Langs`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/i18n/Langs.html) | |
| [`Messages`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/i18n/Messages$.html) | [`MessagesApi`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/i18n/MessagesApi.html) | `preferred`メソッドの1つを使うと、[`Messages`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/i18n/Messages.html) インスタンスを得ることができます。 |
| [`DB`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/db/DB$.html) |[`DBApi`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/db/DBApi.html) またはそれ以上のもの、[`Database`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/db/Database.html) | `@NamedDatabase` アノテーションを使って特定のデータベースを取得できます。|
[`Cache`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/cache/Cache$.html) | [`CacheApi`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/cache/CacheApi.html) 以上 | `@NamedCache` アノテーションを使って特定のキャッシュを得ることができます。|
| [`Cached` object](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/cache/Cached$.html) | [`Cached` instance](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/cache/Cached.html)| コンパニオンオブジェクトの代わりに注入されたインスタンスを使用します。`@NamedCache` アノテーションを使うことができます。|
| [`Akka`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/concurrent/Akka$.html) | N/A | もはや必要ではなく、 `ActorSystem`に依存関係を宣言するだけです。 |
| [`WS`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/ws/WS$.html) | [`WSClient`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/ws/WSClient.html) | |
| [`Crypto`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/Crypto$.html) | [`Crypto`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/Crypto.html) | |
| [`GlobalSettings`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/GlobalSettings.html) | [`HttpErrorHandler`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/http/HttpErrorHandler.html), [`HttpRequestHandler`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/http/HttpRequestHandler.html), and [`HttpFilters`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/http/HttpFilters.html) | 下記の [GlobalSettings] セクションの詳細をお読みください。|

#### Java

| Old API | New API | Comments |
| ------- | --------| -------- |
| [`Lang`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/i18n/Lang.html) | [`Langs`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/i18n/Langs.html) | `Lang`オブジェクトのインスタンスはまだ使えます。 |
| [`Messages`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/i18n/Messages.html) | [`MessagesApi`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/i18n/MessagesApi.html) | `preferred`メソッドの1つを使って、` Messages`インスタンスを取得することができます。そして `at`を使ってそのlangのメッセージを取得することができます。|
| [`DB`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/db/DB.html) | [`DBApi`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/db/DBApi.html) or better, [`Database`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/db/Database.html) | [`@NamedDatabase`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/db/NamedDatabase.html) アノテーションを使用して特定のデータベースを取得できます。|
| [`JPA`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/db/jpa/JPA.html) | [`JPAApi`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/db/jpa/JPAApi.html) | |
| [`Cache`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/cache/Cache.html) | [`CacheApi`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/cache/CacheApi.html) | [`@NamedCache`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/cache/NamedCache.html) アノテーションを使用して特定のキャッシュを取得できます。|
| [`Akka`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/Akka.html) | N/A | もはや必要ではなく、 `ActorSystem`に依存関係を宣言するだけです。 |
| [`WS`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/ws/WS.html) | [`WSClient`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/ws/WSClient.html) | |
| [`Crypto`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/Crypto.html) | [`Crypto`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/Crypto.html) |古い静的メソッドは削除されています。インスタンスは `play.Play.application().injector().instanceOf(Crypto.class)` を使って静的にアクセスできます。 |
| [`GlobalSettings`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/GlobalSettings.html) | [`HttpErrorHandler`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/http/HttpErrorHandler.html), [`HttpRequestHandler`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/http/HttpRequestHandler.html), and [`HttpFilters`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/http/HttpFilters.html) | 下記の [GlobalSettings] セクションの詳細をお読みください。|

### GlobalSettings

依存関係注入を利用したい場合は、できるだけ多くのコードを `GlobalSettings`実装クラスから外すことをお勧めします。詳細については、[`GlobalSettings` 移行ドキュメント](http://qiita.com/nazoking@github/items/dbde0f7aae02e92f5dbd) を読んでください。

## `Plugin` は廃止されました

Java [`play.Plugin`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/Plugin.html) とScala [`play.api.Plugin`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/Plugin.html) の両方の型は非推奨です。[`play.api.inject.Module`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/inject/Module.html) を使用するようにコードを更新するには、[Plugin to Module](https://playframework.com/documentation/2.6.x/PluginsToModules)を読んでください。

## 設定の変更

Play 2.4では `reference.conf`を使用して、すべてのプロパティのデフォルト値を文書化して指定します。[ここ](https://github.com/playframework/playframework/find/master) に行き、 `reference.conf` というファイルを探して簡単に見つけることができます。

さらに、Playではより多くの名前空間設定プロパティが設定されています。通常、古い設定パスは動作しますが、使用すると、実行時に非推奨警告が出力されます。変更されたキーの概要を以下に示します。

|古いキー|新しいキー|
| ------------------------- | ---------------------------------- |
| `application.secret`      | `play.crypto.secret`               |
| `application.context`     | `play.http.context`                |
| `session.*`               | `play.http.session.*`              |
| `flash.*`                 | `play.http.flash.*`                |
| `application.router`      | `play.http.router`                 |
| `application.langs`       | `play.i18n.langs`                  |
| `application.lang.cookie` | `play.i18n.langCookieName`         |
| `parsers.text.maxLength`  | `play.http.parser.maxMemoryBuffer` |
| `csrf`                    | `play.filters.csrf`                |
| `evolutions.*`            | `play.evolutions.*`                |
| `applyEvolutions.<db>`    | `play.evolutions.db.<db>.autoApply`|
| `ws`                      | `play.ws`                          |

### Akka設定

Play 2.4には1つのアクターシステムしかありません。以前は、内部のアクターシステムは `play.akka`で設定され、Akkaプラグインは` akka`の下で設定されていました。新しい複合アクターシステムは、 `akka`の下で構成されています。`play.akka`にはアクターシステムの設定はありません。しかし、いくつかのPlay固有の設定は `play.akka`プレフィックスの下に与えられます。

アクターシステムの設定方法を変更したい場合は、 `play.akka.config = "my-akka"` を設定することができます。ここで `my-akka`は選択した設定接頭辞です。

詳細は、 [Java](https://playframework.com/documentation/2.6.x/JavaAkka) または [Scala](https://playframework.com/documentation/2.6.x/ScalaAkka) Akkaのページを参照してください。

####スレッドプールの設定

これまでは、2つのアクターシステムがわずかに異なるスレッドプール構成を持っていました。アクターシステムが1つしかないので、構成がマージされました。また、ほとんどのPlayアプリケーションでパフォーマンスを向上させるLIFO(スタックベース)スケジューリングルールを追加しました。

次の設定は、Play 2.4の新しいデフォルトです。テストでは優れたパフォーマンスを示していますが、すべてのアプリケーションが異なるため、それらを調整したり、Play 2.3の設定に戻したりする必要があります。`application.conf`でこれらの値をオーバーライドすることで、これを行うことができます。新しい設定は次のとおりです：

```
akka {
  actor {
    default-dispatcher {
      fork-join-executor {
        parallelism-factor = 1.0
        parallelism-max = 24
        task-peeking-mode = LIFO
      }
    }
  }
}
```

特に、[デフォルトのAkka設定](http://doc.akka.io/docs/akka/2.3.11/general/configuration.html#listing-of-the-reference-configuration) を試してみてください。

```
akka {
  actor {
    default-dispatcher {
      fork-join-executor {
        parallelism-factor = 3.0
        parallelism-max = 64
        task-peeking-mode = FIFO
      }
    }
  }
}
```

詳細については、[スレッドプール構成セクション](https://playframework.com/documentation/2.6.x/ThreadPools) を参照してください。

### HttpRequestHandler

Playがデフォルトで使用するHttpRequestHandlerは、従来の `GlobalSettings`メソッドに委譲します。アプリケーションで `GlobalSettings`を使用していない場合は、ハンドラを変更してパフォーマンスを少し向上させることができます。あなたはあなたの設定に以下を追加することでそれを行うことができます：

```
play.http.requestHandler = "play.http.DefaultHttpRequestHandler"
```

###ロギング

ログは[logback設定ファイル](http://logback.qos.ch/manual/configuration.html) を介してのみ設定されるようになりました。

## JDBC接続プール

デフォルトのJDBC接続プールは、BoneCPの代わりに [HikariCP](http://brettwooldridge.github.io/HikariCP/) によって提供されています。

BoneCPに戻すには、 `application.conf`に` play.db.pool`プロパティを設定します：

```
play.db.pool = bonecp
```

Play接続プールで使用できる設定オプションの全範囲は、Play JDBC [`reference.conf`](resources/confs/play-jdbc/reference.conf) にあります。

次の例外が発生することがあります。

```
Caused by: java.sql.SQLException: JDBC4 Connection.isValid() method not supported, connection test query must be configured
```
これは、JDBCドライバがConnection.isValid()をサポートしていない場合に発生します。最新のバージョンのJDBC-Driverを使用していることを確認するのが最も速く推奨される修正です。最新版へのアップグレードが役に立たない場合は、application.confに `connectionTestQuery`を次のように指定することができます
```
#specify a connectionTestQuery. JDBC-Driverをアップグレードしても問題が解決しない場合にのみ実行してください
db.default.hikaricp.connectionTestQuery="SELECT TRUE"
```
これに関する詳細については、 [HikariCP Github Page](https://github.com/brettwooldridge/HikariCP/) を参照してください。

## ボディパーサー

デフォルトのボディパーサは `play.api.mvc.BodyParsers.parse.default`になりました。`anyContent`パーサと似ていますが、PATCH、POST、およびPUTリクエストのボディのみを解析する点が異なります。他のメソッドのリクエストのためにボディをパースするには、 `anyContent`パーサを` Action`に明示的に渡します。

```scala
def foo = Action(play.api.mvc.BodyParsers.parse.anyContent) { request =>
  Ok(request.body.asText)
}
```

### 最大体長

ScalaとJavaの両方で、構成された最大ボディー長が処理され、適用される方法には、いくつかの重要な変更がありました。

新しいプロパティー `play.http.parser.maxDiskBuffer`は、ディスクにバッファリングする可能性のあるパーサによって解析されるボディーの最大長を指定します。これには、rawボディパーサーと `multipart/form-data` パーサーが含まれます。デフォルトでは10MBです。

`multipart/form-data` パーサーの場合、すべてのテキストデータ部分の集合長は、設定された `play.http.parser.maxMemoryBuffer` 値によって制限されます。デフォルト値は100KBです。

すべての場合において、最大長解析プロパティの1つを超えると、413応答が返されます。これには、 `BodyParser.Of` アノテーションの `maxLength`プロパティを明示的にオーバーライドしたJavaアクションが含まれます。 - 以前は、カスタム最大長が設定されていれば、 `RequestBody.isMaxSizeExceeded`フラグをチェックするのはJavaの動作まででしたが、このフラグは廃止されました。

さらに、Javaアクションは、設定された最大長より大きい `BodyParser.Of.maxLength` 値を宣言できるようになりました。

## JSON APIの変更

JSONルックアップのセマンティクスはわずかに変更されています。`JsUndefined` は `JsValue` 型階層から削除され、 `jsv\foo` や `jsv(bar)` の形式のすべてのルックアップは[`JsLookup`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/json/JsLookup.html) に移されました。`JsValue`の代わりに [`JsLookupResult`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/json/JsLookupResult.html) を返します。

あなたがフォームのコードを持っているなら

```scala
val v: JsValue = json \ "foo" \ "bar"
```

プロパティが存在することがわかっている場合、次のコードは同等です。

```scala
val v: JsValue = (json \ "foo" \ "bar").get
```

プロパティが存在することがわかっていないい場合は、 `JsUndefined`ケースを安全に処理するためにパターンマッチングや [`JsLookupResult`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/json/JsLookupResult.html) を使ってください。例えば

```scala
val vOpt: Option[JsValue] = (json \ "foo" \ "bar").toOption
```

### JsLookup

すべてのJSONトラバーサルメソッドは、 [`JsLookup`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/json/JsLookup.html) クラスに移動されました。これは `JsValue` または `JsLookupResult`型のすべての値に暗黙的に適用されます。`apply` 、`\` 、 `\\` メソッドに加えて、 `head`、 `tail`、 `last` メソッドがJSON配列に追加されています。 `\\`を除くすべてのメソッドは、未定義の値の処理に役立つ `JsValue`のラッパーである [`JsLookupResult`](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/json/JsLookupResult.html) を返します。

`as[A]`、 `asOpt[A]`、 `validate[A]`メソッドも `JsLookup`に存在しますので、以下のようなコードではソースを変更する必要はありません：

```scala
val foo: Option[FooBar] = (json \ "foo" \ "bar").asOpt[FooBar]
val bar: JsResult[Baz] = (json \ "baz").validate[Baz]
```

これらの変更の結果として、コードでは、 `JsValue` 型のすべての値がJSONにシリアライズ可能であると想定できるようになりました。

### Options の読み込み

`OptionReads` は2.4ではデフォルトでは利用できません。`jsv.validate[Option[A]]` という形式のコードをお持ちの場合は、次のいずれかの方法で書き直す必要があります：

1. `JsNull` と未定義ルックアップ結果の両方を `None` にマップするには、 `jsv.validateOpt[A]` を使います。これは典型的にはあなたが望むものです。
2. すべての検証エラーを `None` にマップするには、 `JsSuccess(jsv.asOpt[A])` を使います。これは、2.3で `Option` を読んだときのものでした。
3. `JsNull` を `None` にマッピングし、存在する場合は値を検証するには、 `jsv.validate(Reads.optionWithNull[A])` を使います。値が存在しない場合、結果は `JsError` になります。

機能コンビネータを使って `Reads` を構築するとき、あなたはおそらく、

```scala
(JsPath \ "property").read[Option[String]]
```

や

```scala
(JsPath \ "property").readNullable[String]
```

これは上記(1)と同じです。これは、 `JsPath.writeNullable` を伴う `Writes` と `JsPath.formatNullable` を用いた `Format` にも当てはまります。`readNullable` は ` JsSuccess(None)` ではなく、最後のノードの前にノードが見つからなかった場合に `JsError` を返します。

最後に、 `Seq[Option[String]]` のような `Option` のための `Reads` を必要とする型のシリアライザを作る問題にぶつかるかもしれません。この場合、 `Option[String]` の読み込みを作成してスコープ内にあることを確認するだけです：

```scala
implicit val optionStringReads: Reads[Option[String]] = Reads.optionWithNull[String]
```

## テストの変更

[`FakeRequest`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/test/FakeRequest.html) は [`RequestBuilder`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/mvc/Http.RequestBuilder.html) に置き換えられました。

Javaテストで使用される逆引きルータは削除されました。refルータに渡された `Helpers.call` への呼び出しは、標準の逆方向ルータ参照または `RequestBuilder` のどちらかをとる `Helpers.route` への呼び出しに置き換えることができます。

## Java TimeoutExceptions

Java APIを使用する場合、[`F.Promise`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/F.Promise.html) はjavaのチェック例外 `TimeoutException`](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html) ではなく、未チェック例外 [` F.PromiseTimeoutException`s](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/F.PromiseTimeoutException.html) を投げます。以前に使用された `TimeoutExceptions` は、 `throws` キーワードで正しく宣言されていませんでした。 `throws`キーワードを使うようにAPIを変更するのではなく、ユーザがメソッドに` throws 'を宣言しなければならないことを意味するので、例外は新しい未チェックタイプに変更されました。詳細については、[＃1227](https://github.com/playframework/playframework/pull/1227) を参照してください。

|古いAPI |新しいAPI |コメント|
| ------- | --------| -------- |
| [`TimeoutException`](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html) | [`F.PromiseTimeoutException`](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/F.PromiseTimeoutException.html) | |

## WSクライアント

WSRequestHolderは、[Scala](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/ws/WSRequest.html) と [Java](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/ws/WSRequest.html) のWSRequestに名前が変更されました。 。以前の `WSRequest`クラスは、OAuth機能のためにWSに内部でのみ使用されていたため、削除されました。

WSはAsyncHttpClient 1.8.xから1.9.xにアップグレードされました。このライブラリには、そのライブラリを直接使用または設定すると、多くの急変する変更が含まれています。詳細については、[AsyncHttpClient Migration Guide](https://github.com/AsyncHttpClient/async-http-client/blob/master/MIGRATION.md) を参照してください。AsyncHttpClient 1.9.xへのアップグレードにより、HTTPSのSNI(Server Name Indication)が有効になります。これにより、CloudflareなどのHTTPSベースのCDNでSNIに大きく依存する多くの問題が解決されます。

WSの設定が変更されました：

* `ws.acceptAnyCertificate`は、` play.ws.ssl.loose.acceptAnyCertificate`という緩やかな設定の下で、検証なしで盲目的にX.509証明書を受け入れることの安全性をより良く示すために移動されました。
* `ws.ssl.debug`の設定はブール値として再定義されました。たとえば` play.ws.ssl.debug.all = true`です。詳細については、[SSLのデバッグ](https://www.playframework.com/documentation/2.4.x/DebuggingSSL) を参照してください。
* `ws.ssl.disabledSignatureAlgorithms` と `ws.ssl.disabledKeyAlgorithms` は、 `play.ws.ssl.disabledSignatureAlgorithms = ["MD2", "MD4", "MD5"]` のように文字列の配列として再定義されています。

AsyncHttpClient 1.9.xのアップグレードのために、いくつかの設定は以前のバージョンのAsyncHttpClientConfigと同じ名前になっていません。ビルダー。混乱を減らすために、WS設定から1.9.x AsyncHttpClientConfigへのマップを示します。ビルダー：

* `play.ws.ning.connectionTimeout` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setConnectTimeout(int)">setConnectTimeout</a>
* `play.ws.ning.idleTimeout` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setReadTimeout(int)">setReadTimeout</a>
* `play.ws.ning.followRedirects` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setFollowRedirect(boolean)">setFollowRedirect</a>
* `play.ws.ning.compressionEnabled` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setCompressionEnforced(boolean)">setCompressionEnforced</a>
* `play.ws.ning.allowPoolingConnection` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setAllowPoolingConnections(boolean)">setAllowPoolingConnections</a>
* `play.ws.ning.allowSslConnectionPool` ->  <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setAllowPoolingSslConnections(boolean)">setAllowPoolingSslConnections</a>
* `play.ws.ning.maxConnectionsTotal` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setMaxConnections(int)">setMaxConnections</a>
* `play.ws.ning.maxConnectionLifetime` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setConnectionTTL(int)">setConnectionTTL</a>
* `play.ws.ning.idleConnectionInPoolTimeout` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setPooledConnectionIdleTimeout(int)">setPooledConnectionIdleTimeout</a>
* `play.ws.ning.webSocketIdleTimeout` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setWebSocketTimeout(int)">setWebSocketTimeout</a>
* `play.ws.ning.maxNumberOfRedirects` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setMaxRedirects(int)">setMaxRedirects</a>
* `play.ws.ning.disableUrlEncoding` -> <a href="http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/AsyncHttpClientConfig.Builder.html#setDisableUrlEncodingForBoundedRequests(boolean)">setDisableUrlEncodingForBoundedRequests</a>

WSはOAuth署名の電卓を[Signpost](https://github.com/mttkay/signpost) からAsyncHttpClientの [OAuthCalculator](http://static.javadoc.io/com.ning/async-http-client/1.9.22/com/ning/http/client/oauth/OAuthSignatureCalculator.html) に変更しました。Signpostは依然としてリクエストトークンとアクセストークンを取得するために使用されます。これはアプリケーションレベルの変更を必要とすべきではありませんが、予期しないOAuthの失敗の場合は注意する価値があります。

最近のTLSの脆弱性のために、安全でないHTTPS構成を非難する活動が増えています。[RFC 7465](https://tools.ietf.org/html/rfc7465)によれば、RC4暗号スイートは廃止予定の暗号のリストに追加されており、デフォルトでは利用できません。それらは `play.ws.ssl.enabledCiphers` と ` play.ws.ssl.loose.allowWeakCiphers`設定を使って暗号スイートとして明示的に有効にすることができます。TLSのIETF推奨設定については、[RFC 7525](https://tools.ietf.org/html/rfc7525) を見直してください。

## Crypto API

Play 2.4のAES暗号化では、[初期化ベクトル](http://en.wikipedia.org/wiki/Initialization_vector)を使用して各暗号化をランダム化するようになりました。Play暗号化形式が変更され、初期化ベクトルのサポートが追加されました。

Play 2.4で使用される新しいAES変換のフルネームは `AES / CTR / NoPadding`です。古い変換は `AES / ECB / PKCS5Padding`でした。[`CTR`](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29)モードは` ECB`モードよりはるかに安全です。これまでのように、 `play.crypto.aes.transformation`設定オプションを設定することで、Playの暗号化変換をオーバーライドすることができます。Play 2.4では、[JREでサポートされている変換](http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher)を使用することができます。初期化ベクトル。

Play 2.4は新しい暗号化形式を使用しますが、以前のバージョンのPlayで暗号化されたデータを読み取ることができます。ただし、以前のバージョンのPlay **では、Play 2.4で暗号化されたデータを読み取ることができません。Play 2.4アプリケーションで古い形式のデータを生成する必要がある場合は、[Play 2.3 Crypto code](https://github.com/playframework/playframework/blob/2.3.6/framework/)のアルゴリズムをコピーしてください。 src / play / src / main / scala / play / api / libs / Crypto.scala＃L187-L277)。

次の表は、Playのさまざまなバージョンでサポートされている暗号化形式を示しています。古いバージョン_は古いバージョンのPlayで使用されています。_新しいフォーマットI_は、設定された暗号が初期化ベクトルを使用しない場合、Play 2.4で使用されます。_新しいフォーマットII_は、初期化ベクトルが必要な場合に使用されます。

フォーマット|エンコーディング|Play2.3 ||Play2.4 ||
---- | ----
古いフォーマット | _hex(cipher(plaintext))_ | writes | reads | | reads
新しいフォーマット I | "1-" + _base64(cipher(plaintext))_ | | | writes | reads
新しいフォーマット II | "2-" + _base64(iv + cipher(plaintext, iv))_ | | | writes | reads

[Java Crypto API](https://www.playframework.com/documentation/ja/2.4.x/api/java/play/libs/Crypto.html) の使用方法は、出力が異なる場合でも変わりません。

Java：
import play.libs.Crypto;

String enc = Crypto.encryptAES(orig);
String dec = Crypto.decryptAES(enc);
```

[Scala Crypto API](https://www.playframework.com/documentation/ja/2.4.x/api/scala/play/api/libs/Crypto.html) の使い方も同じです：

```scala
import play.api.libs.Crypto

val enc = Crypto.encryptAES(orig)
val dec = Crypto.decryptAES(enc)
```
## Anorm

新しいAnormバージョンには、さまざまな修正と改善が含まれています。[ここ](https://playframework.com/documentation/2.6.x/Anorm)を読んで詳細を調べてください。

## HTTPサーバーの設定

高度なNetty設定オプション、つまり `http.netty.option`という接頭辞が付いたオプションは、代わりに` play.server.netty.option`という接頭辞を使用する必要があります。

## I18n

あなたのアプリケーションがサポートする言語を指定するための設定キーは `application.langs`から` play.i18n.langs`に変更されました。また、コンマで区切られた文字列ではなく、リストになっています。インスタンスごと：

```
play.i18n.langs = [ "en", "en-US", "fr" ]
```

### Scala

i18n APIを使用するには、 `` Lang`ではなく `` Messages``(api / scala / play / api / i18n / Messages.html)の値を暗黙的に指定する必要があります。 `Messages`型は` Lang`と `MessagesApi`(api / scala / play / api / i18n / MessagesApi.html)を集約します。

つまり、テンプレートを変更して `Lang`の代わりに暗黙の` Messages`パラメータを取る必要があります：

```scala
@(form: Form[Login])(implicit messages: Messages)
...
```

あなたのコントローラから、あなたは `` play.api.i18n ''を混合することで、このような暗黙の `Messages`値を得ることができます。あなたの暗黙のスコープ内に `RequestHeader`値がある限り、あなたは暗黙の` Messages`値を与えるコントローラの特質(I18nSupport`)(api / scala / play / api / i18n / I18nSupport.html)`I18nSupport`特性は抽象メンバ` def messagesApi：MessagesApi`を持っていますので、あなたのコードは通常以下のようになります：

```scala
import javax.inject.Inject
import play.api.i18n.{MessagesApi, I18nSupport}
import play.api.mvc.Controller

class MyController @Inject() (val messagesApi: MessagesApi)
  extends Controller with I18nSupport {

}
```

`I18nSupport`特性を持つクラスを注入するのではなく、コントローラが静的コントローラオブジェクトを引き続き使用するようにしたい場合は、より簡単な移行パスもサポートされています。上で説明したように、暗黙の `Messages`パラメータを取るようにテンプレートを変更した後、以下のインポートをあなたのコントローラに追加してください：

```scala
import play.api.i18n.Messages.Implicits._
```

このインポートは暗黙的なスコープ内に `Lang`と` Application`がある限り暗黙の `Messages`値をもたらします(感謝してコントローラは既に` Lang`を提供しています。 `play 'をインポートして現在実行中のアプリケーションを得ることができます。 API。Play.current`)。

{0}{0}{1}Java：{/1}{/0}{/0}

APIはPlay 2.3を使用してコードと下位互換性があるため、移行手順はありません。それにもかかわらず、Java i18n APIを使用する前にPlayアプリケーションを起動する必要があることに注意してください。プロジェクトを実行するときは常にそうでなければなりませんが、テストコードがアプリケーションを起動するとは限りません。テストを実行する前に、アプリケーションの起動方法を知るには対応する[documentation page](https://playframework.com/documentation/2.6.x/JavaTest)を参照してください。

## ディストリビューション

以前は、すべてのリソースをディストリビューションの `conf` ディレクトリに追加しましたが、 `conf` ディレクトリをクラスパスに追加しませんでした。今Playはデフォルトで `conf` ディレクトリをクラスパスに追加します。

`PlayKeys.externalizeResources：= false`をセットすることでこれを無効にすることができます。これにより、 `conf` ディレクトリは配布物には作成されず、クラスパスには存在しません。アプリケーションの `conf` ディレクトリの内容は、アプリケーションのjarファイルに含まれているため、クラスパス上に残ります。

Java Persistence API(JPA)を使用している場合は、アプリケーションをデプロイするためにこのオプションをfalseに設定する必要があります。そうしないと、 `Entity X is not mapped` というエラーメッセージが表示されます。これは、ローカル開発には必要ありません。

### Debianパッケージ作成の変更点

[sbt-native-packager](https://github.com/sbt/sbt-native-packager)がアップグレードされました。このため、次の調整が必要な場合があります。
* `/etc/default/$appname` ファイルの構文は、コマンドラインパラメータの単純なリストから、起動/停止スクリプトがソースとなるシェルスクリプトに変更され、環境変数を設定することができます。
*既定のファイルの古い構文に相当するのは、アーカイブの `conf` フォルダにある `application.ini` ファイルです。
*デフォルトファイルは `SystemV` Initスクリプトのみから取得されます.Updateはこのファイルを現在無視します。ビルドを変更して `SystemV`互換のパッケージを作成するには、これをbuild.sbtに追加してください：

```
import com.typesafe.sbt.packager.archetypes.ServerLoader.{SystemV, Upstart}

serverLoading in Debian := SystemV
```

*必要なその他の変更は、[sbt-native-packagerリリースノート](https://github.com/sbt/sbt-native-packager/releases)にあります。


## その他

### これ以上OrderedExecutionContext

不思議な `OrderedExecutionContext` は、レガシーアプリケーションをサポートするためにいくつかのバージョンでPlayの[held](https://playframework.com/documentation/2.6.x/Migration22＃Concurrent-F.Promise-execution)を保持していました。それはめったに使用されず、削除されました。なんらかの理由で `OrderedExecutionContext` が必要な場合は、[Play 2.3ソース](https://github.com/playframework/playframework/blob/2.3.x/framework/src/play/src/main/scala/play/core/j/OrderedExecutionContext.scala) に基づいて独自の実装を作成することができます。あなたがこのクラスについて聞いていないなら、何もする必要はありません。

### サブプロジェクトアセット

サブプロジェクト内の資産は、デフォルトでは/ lib / [サブプロジェクト]に配置され、ルートプロジェクト/異なるサブプロジェクト内で同じ名前のファイルが互いに干渉することなく使用できます。

アプリ内でアセットルーティングが正しく機能するようにするには、以下を変更する必要があります：

    GET     /assets/*file               controllers.myModule.Assets.at(path="/public", file)

これに

    GET     /assets/*file               controllers.myModule.Assets.at(path="/public/lib/myModule", file)