Play2.4 -> Play2.5に移行する方法と解決したエラーたち

# 移行方法
以下の二つを書き換える

- project/build.properties
`sbt.version=0.13.8`
↓
`sbt.version=0.13.11`

- project/plugins.sbt
`addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.6")`
↓
`addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.0")`

終わったらactivator eclipseとして、2.5に更新すると共にプロジェクトファイルも同時に一新する
（Eclipseじゃない人はactivator updateやactivator runで良さそう）

すると非推奨パッケージとコンパイルエラーが出るわ出るわ

# コンパイル時のエラーを直す
## エラー: 不適合な型: ObjectをFileに変換できません:
- `File file = picture.getFile();`

どうやらplay.mvc.Http.MultipartFormDataと
play.mvc.Http.MultipartFormData.FilePartにはジェネリックスが付くようになったらしい

```
MultipartFormData body = request().body().asMultipartFormData();
FilePart picture = body.getFile("picture");
```
↓修正

```
MultipartFormData<File> body = request().body().asMultipartFormData();
FilePart<File> picture = body.getFile("picture");
```

## エラー: DynamicFormに適切なコンストラクタが見つかりません(引数がありません)
- `DynamicForm form = new DynamicForm().bindFromRequest();`

Formはファクトリーメソッドを使って作るようになった模様
DynamicFormを作るにはFormFactoryのform()を引数なしで呼べば良い

１. コントローラーにFormFactoryとInjectをインポート

```
import javax.inject.Inject;
import play.data.FormFactory;
```

２. コントローラーにフィールド追加

```
@Inject
FormFactory formFactory;
```

３. フォーム部分を書き換え
`DynamicForm requestData = formFactory.form().bindFromRequest();`


## CSRF Filters
- エラー: Filtersはabstractでなく、HttpFilters内のabstractメソッドfilters()をオーバーライドしません
- エラー: Filtersのfilters()はHttpFiltersのfilters()を実装できません
- 戻り値の型play.api.mvc.EssentialFilter[]はplay.mvc.EssentialFilter[]と互換性がありません
- エラー: メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません

恐れることなくフィルタークラスを変更

```
import play.http.HttpFilters;
import play.api.mvc.EssentialFilter;　// ←☆
import play.filters.csrf.CSRFFilter;
import javax.inject.Inject;

public class Filters implements HttpFilters {

    @Inject CSRFFilter csrfFilter;

    @Override
    public EssentialFilter[] filters() {
        return new EssentialFilter[] { csrfFilter };　// ←☆
    }
}
```

↓

```
import play.http.HttpFilters;
import play.mvc.EssentialFilter;　// ←☆
import play.filters.csrf.CSRFFilter;
import javax.inject.Inject;

public class Filters implements HttpFilters {

    @Inject CSRFFilter csrfFilter;

    @Override
    public EssentialFilter[] filters() {
        return new EssentialFilter[] { csrfFilter.asJava() };　// ←☆
    }
}
```

# 非推奨パッケージの置き換え
## play.cache.Cache → play.cache.CacheApi

１．コントローラーにフィールド追加

```
@Inject
CacheApi cache;
```
２．CacheApiを使うように変更
`Cache.set(token, info, 60 * 60);`
↓
`cache.set(token, info, 60 * 60);`

### ViewでCacheを使ってる場合

Viewの引数にコントローラーでInjectしたフィールドを渡せば良いらしい

１.コントローラーにCacheApiのフィールド追加
```
@Inject
CacheApi cache;
```

２．ViewにCacheApiをインポート
`@import play.cache.CacheApi`

３．Viewのテンプレート引数にCacheApiを追加
`@(user: models.entity.User, cache: CacheApi)`

４．ViewでCacheApiを使うように変更
`Cache.get(session.get("userToken"))`
↓
`cache.get(session.get("userToken"))`

５．コントローラーのレンダリング部分を修正
`return ok(user.render(userOps.get(), cache));`


## play.Routes → play.routing.JavaScriptReverseRouter

１．コントローラーにplay.routing.JavaScriptReverseRouterをインポート
`import play.routing.JavaScriptReverseRouter;`

２．JavaScriptのルーティング部分を書き換え

```
public Result getJSRoutes() {
	return ok(Routes.javascriptRouter("jsRoutes",
	controllers.routes.javascript.FooController.bar()));
}
```
↓

```
public Result getJSRoutes() {
	return ok(JavaScriptReverseRouter.create("jsRoutes",
	controllers.routes.javascript.FooController.bar()));
}
```

# 移行に役立つと思われるリンク
- https://www.playframework.com/documentation/2.5.x/Home
公式ドキュメント

- https://www.playframework.com/documentation/2.5.x/Migration25
公式マイグレーションガイド

- https://www.playframework.com/documentation/2.5.x/api/java/index.html
公式APIドキュメント

公式を見れば大体解決する！