文档

§Play 2.4 迁移指南

本指南介绍了从 Play 2.3 迁移到 Play 2.4 的步骤。如果您需要从更早版本的 Play 迁移,则必须首先遵循 Play 2.3 迁移指南

除了本页面的信息外,还有一些主题的更详细的迁移信息。

§Java 8 支持

对 Java 6 和 Java 7 的支持已取消,Play 2.4 现在需要 Java 8。此决定是基于 Java 7 于 2015 年 4 月达到生命周期结束 的事实。此外,Java 8 使得 API 更简洁,并且对函数式编程风格有更好的支持。如果您尝试将 Play 2.4 与 Java 6/7 一起使用,您将收到以下错误

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

一个 java.lang.UnsupportedClassVersionError 表示使用比编译类文件更早版本的 Java 读取类文件不受支持。

注意:Scala 2.10 并不完全支持所有 Java 8 语言特性,例如接口上的静态方法。如果您的项目包含使用 Java 8 中存在的这些新特性的 Java 代码,请升级到 Scala 2.11.6+。请参阅 sbt 文档,了解如何将 scalaVersion 设置为您的项目。

§构建变更

在您可以在 sbt 中加载/运行 Play 项目之前,需要执行以下步骤来更新您的 sbt 构建。

§Play 升级

更新 project/plugins.sbt 中的 Play 版本号以升级 Play

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

§sbt 升级

Play 2.4 现在需要至少 sbt 0.13.8。更新您的 project/build.properties,使其读取

sbt.version=0.13.8

§Specs2 支持在单独的模块中

如果您之前使用过 Play 的 specs2 支持,您现在需要显式地将对该支持的依赖项添加到您的项目中

libraryDependencies += specs2 % Test

如果您使用的是 .scala 构建文件,您需要添加以下导入 import play.sbt.PlayImport._

§数据库演变支持在单独的模块中

以前,Play JDBC 和 JPA 支持都包含对 数据库演变 的支持。现在情况不再如此。因此,如果您正在使用演变,现在需要在项目的构建中显式添加对 evolutions 的依赖项。

libraryDependencies += evolutions

如果您没有使用演变,现在可以安全地从您的 application.conf 中删除 evolutionplugin=disabled

配置键已更改,因此您现在需要使用 play.evolutions.enabled=false 而不是 evolutionplugin=disabled(请参阅 演变配置)。

如果您使用的是 Play Slick 模块(无论是否使用演变),事情都发生了很大变化,因此请务必阅读 Play Slick 迁移指南

§IDE:Eclipse 和 IntelliJ IDEA

Play 不再包含 sbteclipse 或 sbt-idea 插件,这使用户能够独立于 Play 升级 IDE 支持。

Eclipse 支持只需一行额外的代码即可设置,以导入插件。有关详细信息,请参阅 文档

IntelliJ 现在能够原生导入 sbt 项目,因此我们建议您使用它。或者,可以手动安装和使用 sbt-idea 插件,说明可以在 此处 找到。

§Play sbt 插件 API

sbt 插件中的所有类现在都在 play.sbt 包中,如果您使用 .scala 文件来配置您的构建,这一点尤其重要。您需要从 play.sbt.PlayImport 导入标识符才能使用 Play 提供的配置元素。

§playWatchService 重命名

sbt 设置键 playWatchService 已重命名为 fileWatchService

相应的类也已更改。要将 FileWatchService 设置为每两秒轮询一次,请像这样使用它

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

§Play Slick 依赖项

Play Slick 模块已经过重大重构以支持 Slick 3.0。为了顺利升级,请阅读 Play Slick 迁移指南

§Ebean 依赖项

Ebean 已被提取到一个外部项目中,以使其能够拥有独立于 Play 生命周期自身的生命周期。Ebean 字节码增强功能也已从 Play sbt 插件中提取到其自己的插件中。

要将使用 Ebean 的现有 Play 项目迁移到使用新的外部 Ebean 插件,请从 build.sbt 中的 libraryDependencies 中删除 javaEbean,并将以下内容添加到 project/plugins.sbt

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

之后,为您的项目启用 Ebean 插件

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 类。因此,Play Model 类已弃用,建议使用 com.avaje.ebean.Model

§字节码增强

Play 的字节码增强功能(为 Java 属性生成 getter 和 setter)已从 Play 的核心部分中提取出来,成为一个单独管理的项目,可以拥有自己的生命周期。要启用它,请将以下内容添加到您的 project/plugins.sbt 文件中

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

§依赖注入

Play 现在开箱即用地使用 Guice 提供的依赖注入。这是从 Play 中删除全局状态的长期策略的一部分,我们希望在 Play 3.0 版本中完成。将任何应用程序从依赖全局状态迁移到完全没有全局状态是一个很大的任务,如果一次性完成,可能会非常具有破坏性。出于这个原因,我们在 Play 中采用的方法是将更改分散到多个版本中,允许最终用户逐步迁移他们的代码,使其不依赖于全局状态,而不是强制一次性完成。

在实际情况下,我们已确保 Play 2.4 中提供的 API 与 Play 2.3 源代码兼容。这意味着,在许多情况下,有两种方法可以完成事情,一种依赖于全局状态,另一种不依赖于全局状态。我们已更新文档以反映新的依赖注入方法 - 在您仍然想要使用旧 API 并查看有关它们的文档的情况下,通常,Play 2.3 文档仍然相关。

在继续迁移到 Play 2.4 之前,务必阅读有关 Play 中依赖注入的文档。有一些决定需要提前做出。开箱即用,我们提供并鼓励使用 Guice 进行依赖注入,但许多其他依赖注入工具和技术,包括 Scala 中的编译时依赖注入技术都是可能的。您可以在 JavaScala 中阅读有关依赖注入的信息。

§路由

关于依赖注入的最具破坏性的变化之一是,我们现在支持生成两种样式的路由器。第一个是现有的静态样式,这与 Play 2.3 路由器基本相同。它是一个 Scala 单例对象,并假设它调用的所有操作都是 Scala 单例对象或 Java 静态方法。第二个是依赖注入路由器,它是一个在构造函数中声明其依赖项的类。为了说明这两种路由器之间的区别,请考虑以下路由文件

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

静态路由生成器将生成一个路由器,它大致(伪代码)如下所示

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)
  }
}

同时,注入路由生成器将生成一个路由器,它大致如下所示

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 中查找操作,如果您处于过渡期,其中一些操作是静态的,而另一些是注入的,您可能会发现这很有用。

如果您希望切换到注入生成器,请在 build.sbt 中的构建设置中添加以下内容

routesGenerator := InjectedRoutesGenerator

默认情况下,Play 将使用 Guice 自动处理此路由器的连接,但根据您采用的 DI 方法,您可能能够对其进行自定义。

注入路由生成器也支持路由上的 @ 运算符,但它具有稍微不同的含义(因为所有内容都已注入),如果您在控制器前面加上 @,则该控制器不会直接注入,而是该控制器的 JSR 330 Provider 将被注入。例如,这可用于消除循环依赖问题,或者如果您希望每个请求实例化一个新的操作。

此外,Play 现在默认情况下在 router 包中生成路由器,而不是在根包中。这是为了帮助进行依赖注入,因此如果需要,它可以手动创建或绑定,因为根包中的类通常无法引用。

§依赖注入组件

虽然 Play 2.4 不会强制您使用依赖注入版本的组件,但我们鼓励您开始切换到它们。以下表格显示了使用全局状态的旧静态 API 和您应该切换到的新注入 API

§Scala

旧 API 新 API 注释
Lang Langs
消息 MessagesApi 使用其中一种 preferred 方法,您可以获取一个 Messages 实例。
DB DBApi 或更好的,Database 您可以使用 @NamedDatabase 注解获取特定数据库。
缓存 CacheApi 或更好的 您可以使用 @NamedCache 注解获取特定缓存。
Cached 对象 Cached 实例 使用注入的实例而不是伴随对象。您可以使用 @NamedCache 注解。
Akka N/A 不再需要,只需声明对 ActorSystem 的依赖关系
WS WSClient
加密 加密
全局设置 HttpErrorHandlerHttpRequestHandlerHttpFilters 阅读下面 全局设置 部分中的详细信息。

§Java

旧 API 新 API 注释
Lang Langs Lang 对象的实例仍然可以使用
消息 MessagesApi 使用其中一种 preferred 方法,您可以获取一个 Messages 实例,然后可以使用 at 获取该语言的消息。
DB DBApi 或更好的,Database 您可以使用 @NamedDatabase 注解获取特定数据库。
JPA JPAApi
缓存 CacheApi 您可以使用 @NamedCache 注解获取特定缓存。
Akka N/A 不再需要,只需声明对 ActorSystem 的依赖关系
WS WSClient
加密 加密 旧的静态方法已被删除,可以使用 play.Play.application().injector().instanceOf(Crypto.class) 静态访问实例
全局设置 HttpErrorHandlerHttpRequestHandlerHttpFilters 阅读下面 全局设置 部分中的详细信息。

§全局设置

如果您热衷于使用依赖注入,我们建议您尽可能将代码从 GlobalSettings 实现类中移出。阅读 `GlobalSettings` 迁移文档 以了解详细信息。

§Plugin 已弃用

Java play.Plugin 和 Scala play.api.Plugin 类型均已弃用。请阅读 将 Plugin 迁移到 Module,以更新您的代码以使用 play.api.inject.Module

§配置更改

Play 2.4 现在使用 reference.conf 来记录和指定所有属性的默认值。您可以轻松地通过 这里 搜索名为 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 现在只有一个 Actor 系统。之前,内部 Actor 系统配置在 play.akka 下,Akka 插件配置在 akka 下。新的组合 Actor 系统配置在 akka 下。play.akka 下不再有 Actor 系统配置。但是,一些 Play 特定的设置仍然在 play.akka 前缀下给出。

如果您想更改 Actor 系统的配置方式,可以设置 play.akka.config = "my-akka",其中 my-akka 是您选择的配置前缀。

有关更多信息,请参见 JavaScala Akka 页面。

§线程池配置

以前,两个 Actor 系统的线程池配置略有不同。现在只有一个 Actor 系统,配置已合并。我们还添加了一个 LIFO(基于堆栈)调度规则,这应该可以提高大多数 Play 应用程序的性能。

以下设置是 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 设置

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

有关更多信息,请参见 线程池配置部分

§HttpRequestHandler

Play 默认使用的 HttpRequestHandler 会委托给旧的 GlobalSettings 方法。如果您在应用程序中没有使用 GlobalSettings,那么您可以通过更改处理程序来稍微提高性能。您可以在设置中添加以下内容

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

§日志记录

日志记录现在仅通过 logback 配置文件 进行配置。

§JDBC 连接池

默认的 JDBC 连接池现在由 HikariCP 提供,而不是 BoneCP。

Play 连接池可用的所有配置选项可以在 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 驱动程序。如果升级到最新版本没有帮助,您可以在 application.conf 中指定 connectionTestQuery,如下所示

#specify a connectionTestQuery. Only do this if upgrading the JDBC-Driver does not help
db.default.hikaricp.connectionTestQuery="SELECT TRUE"

有关此的更多信息可以在 HikariCP Github 页面 上找到

§主体解析器

默认的主体解析器现在是 play.api.mvc.BodyParsers.parse.default。它类似于 anyContent 解析器,只是它只解析 PATCH、POST 和 PUT 请求的主体。要解析其他方法请求的主体,请将 anyContent 解析器显式传递给 Action

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

§最大主体长度

对于 Scala 和 Java,在处理和应用配置的最大主体长度的方式上有一些小的但重要的更改。

一个新的属性 play.http.parser.maxDiskBuffer 指定了任何由可能缓冲到磁盘的解析器解析的主体的最大长度。这包括原始主体解析器和 multipart/form-data 解析器。默认情况下,这是 10MB。

multipart/form-data 解析器的情况下,所有文本数据部分的总长度受配置的 play.http.parser.maxMemoryBuffer 值限制,该值默认为 100KB。

在所有情况下,当超过最大长度解析属性之一时,将返回 413 响应。这包括显式覆盖了 BodyParser.Of 注释上的 maxLength 属性的 Java 操作 - 以前,Java 操作需要检查 RequestBody.isMaxSizeExceeded 标志(如果配置了自定义最大长度),该标志现在已弃用。

此外,Java 操作现在可以声明一个大于配置的最大长度的 BodyParser.Of.maxLength 值。

§JSON API 更改

JSON 查找的语义略有变化。JsUndefined 已从 JsValue 类型层次结构中移除,所有形式为 jsv \ foojsv(bar) 的查找都已移至 JsLookup。现在它们返回 JsLookupResult 而不是 JsValue

如果您有以下形式的代码

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

如果您知道属性存在,则以下代码等效

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

如果您不知道属性是否存在,我们建议使用模式匹配或 JsLookupResult 上的方法来安全地处理 JsUndefined 案例,例如

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

§JsLookup

所有 JSON 遍历方法都已移至 JsLookup 类,该类隐式应用于所有类型为 JsValueJsLookupResult 的值。除了 apply\\\ 方法外,还为 JSON 数组添加了 headtaillast 方法。除 \\ 外的所有方法都返回 JsLookupResult,它是 JsValue 的包装器,有助于处理未定义的值。

as[A]asOpt[A]validate[A] 方法也存在于 JsLookup 上,因此以下代码不需要任何源代码更改

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

由于这些更改,您的代码现在可以假设所有类型为 JsValue 的值都可序列化为 JSON。

§读取选项

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 时,您很可能希望替换

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

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

这与上面的 (1) 相同。对于 Writes 使用 JsPath.writeNullableFormat 使用 JsPath.formatNullable 也是如此。请注意,如果在最后一个节点之前找不到节点,readNullable 将返回 JsError,而不是 JsSuccess(None)

最后,您可能会遇到为需要 Reads 用于 Option 的类型(例如 Seq[Option[String]])创建序列化程序的问题。在这种情况下,您只需要为 Option[String] 创建一个读取器,并确保它在范围内

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

§测试更改

FakeRequest 已被 RequestBuilder 替换。

Java 测试中使用的反向引用路由器已删除。任何传递反向引用路由器的 Helpers.call 调用都可以替换为 Helpers.route 调用,该调用接受标准反向引用路由器引用或 RequestBuilder

§Java 超时异常

如果您使用 Java API,F.Promise 类现在抛出未经检查的 F.PromiseTimeoutExceptions,而不是 Java 的已检查 TimeoutExceptions。以前使用的 TimeoutExceptions 没有用 throws 关键字正确声明。与其更改 API 以使用 throws 关键字(这意味着用户必须在他们的方法上声明 throws),不如将异常更改为新的未经检查的类型。有关更多信息,请参阅 #1227

旧 API 新 API 注释
TimeoutException F.PromiseTimeoutException

§WS 客户端

WSRequestHolder 已在 ScalaJava 中重命名为 WSRequest。之前的 WSRequest 类已被删除,因为它仅在 WS 内部用于 OAuth 功能。

WS 已从 AsyncHttpClient 1.8.x 升级到 1.9.x,如果直接使用或配置该库,则包含一些重大更改。有关更多详细信息,请参阅 AsyncHttpClient 迁移指南。升级到 AsyncHttpClient 1.9.x 在 HTTPS 中启用了服务器名称指示 (SNI) - 这解决了 HTTPS 基于 CDN(如 Cloudflare)的许多问题,这些 CDN 严重依赖 SNI。

WS 的配置设置已更改

由于 AsyncHttpClient 1.9.x 升级,一些设置不再具有与以前在 1.8.x 版本 AsyncHttpClientConfig.Builder 中相同的名称。为了减少混淆,以下是 WS 设置到 1.9.x AsyncHttpClientConfig.Builder 的映射

WS 已将 OAuth 签名计算器从 Signpost 更改为 AsyncHttpClient 的 OAuthCalculator。Signpost 仍然用于检索请求令牌和访问令牌。这应该不需要任何应用程序级别的更改,但在出现意外的 OAuth 故障时值得注意。

由于最近出现大量 TLS 漏洞,弃用不安全的 HTTPS 配置的活动有所增加。根据 RFC 7465,RC4 密码套件已添加到已弃用密码的列表中,默认情况下不可用。可以使用 play.ws.ssl.enabledCiphersplay.ws.ssl.loose.allowWeakCiphers 设置将它们显式启用为密码套件。请还考虑查看 RFC 7525 以获取 IETF 推荐的 TLS 配置。

§加密 API

Play 2.4 的 AES 加密现在使用 初始化向量 来随机化每次加密。Play 加密格式已更改以添加对初始化向量的支持。

Play 2.4 使用的新的 AES 变换的完整名称是 AES/CTR/NoPadding。旧的变换是 AES/ECB/PKCS5PaddingCTR 模式比 ECB 模式安全得多。与以前一样,您可以通过设置 play.crypto.aes.transformation 配置选项来覆盖 Play 的加密变换。在 Play 2.4 中,可以使用 您的 JRE 支持的任何变换,包括使用初始化向量的变换。

Play 2.4 使用新的加密格式,但它可以读取由早期版本的 Play 加密的數據。但是,早期版本的 Play **将无法** 读取由 Play 2.4 加密的數據。如果您的 Play 2.4 应用程序需要以旧格式生成数据,那么您可能需要从 Play 2.3 Crypto 代码 中复制算法。

下表显示了不同版本的 Play 支持的加密格式。旧格式 由较旧版本的 Play 使用。新格式 I 由 Play 2.4 使用,如果配置的密码不使用初始化向量。新格式 II 用于需要初始化向量时。

格式 编码 Play 2.3 Play 2.4
旧格式 hex(cipher(plaintext)) 写入 读取 读取
新格式 I “1-” + base64(cipher(plaintext)) 写入 读取
新格式 II “2-” + base64(iv + cipher(plaintext, iv)) 写入 读取

即使输出不同,Java Crypto API 的使用方式仍然相同

import play.libs.Crypto;

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

Scala Crypto API 的使用方式也相同

import play.api.libs.Crypto

val enc = Crypto.encryptAES(orig)
val dec = Crypto.decryptAES(enc)

§Anorm

新的 Anorm 版本包含各种修复和改进。阅读 这里 以了解更多信息。

§HTTP 服务器配置

高级 Netty 配置选项,即以 http.netty.option 为前缀的选项,现在必须使用 play.server.netty.option 作为前缀。

§I18n

指定应用程序支持的语言的配置键已从 application.langs 更改为 play.i18n.langs。此外,它现在是一个列表,而不是一个逗号分隔的字符串。例如

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

§Scala

您现在需要有一个隐式的 Messages 值,而不仅仅是 Lang,才能使用 i18n API。Messages 类型聚合了 LangMessagesApi

这意味着您应该更改您的模板以接受一个隐式的 Messages 参数,而不是 Lang

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

从您的控制器中,您可以通过在您的控制器中混合 play.api.i18n.I18nSupport 特性来获得这样的隐式 Messages 值,只要在隐式范围内存在 RequestHeader 值。I18nSupport 特性有一个抽象成员 def messagesApi: MessagesApi,因此您的代码通常看起来像这样

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 参数后,如上所述,将以下导入添加到您的控制器中

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

只要隐式作用域中存在 `Lang` 和 `Application`,此导入就会为您带来一个隐式的 `Messages` 值(值得庆幸的是,控制器已经提供了 `Lang`,您可以通过导入 `play.api.Play.current` 来获取当前正在运行的应用程序)。

§Java

该 API 应该与您使用 Play 2.3 的代码向后兼容,因此没有迁移步骤。但是,请注意,您必须在使用 Java i18n API 之前启动 Play 应用程序。在运行项目时,这应该始终是这种情况,但是您的测试代码可能并不总是启动应用程序。请参阅相应的 文档页面,了解如何在运行测试之前启动应用程序。

§分发

以前,Play 将所有资源添加到分发中的 `conf` 目录,但没有将 `conf` 目录添加到类路径。现在,Play 默认将 `conf` 目录添加到类路径。

可以通过设置 `PlayKeys.externalizeResources := false` 来关闭此功能,这将导致在分发中不创建任何 `conf` 目录,并且它也不会在类路径上。应用程序 `conf` 目录的内容仍然会在类路径上,因为它是应用程序 jar 文件的一部分。

请注意,如果您使用的是 Java 持久性 API (JPA),则需要将此选项设置为 false 才能部署应用程序。否则,您将收到错误消息:`实体 X 未映射`。这对于本地开发不是必需的。

§Debian 包创建中的更改

sbt-native-packager 已升级。因此,可能需要进行以下调整
* ` /etc/default/$appname` 文件的语法已从简单的命令行参数列表更改为一个 shell 脚本,该脚本由启动/停止脚本源代码,允许您设置环境变量。
* 等效于旧语法默认文件的是存档 `conf` 文件夹中的 `application.ini` 文件。
* 默认文件仅由 `SystemV` Init 脚本源代码 - Upstart 目前忽略此文件。要更改您的构建以创建与 `SystemV` 兼容的软件包,请将此添加到您的 build.sbt 中

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

serverLoading in Debian := SystemV

§杂项

§不再使用 OrderedExecutionContext

神秘的 OrderedExecutionContext 在 Play 中保留了几个版本,以支持旧版应用程序。它很少被使用,现在已被移除。如果您仍然出于某种原因需要 OrderedExecutionContext,您可以根据 Play 2.3 源代码 创建自己的实现。如果您从未听说过此类,那么您无需执行任何操作。

§子项目资产

现在,子项目中的所有资产默认情况下都放置在 /lib/[subproject] 中,以允许根项目中具有相同名称的文件/不同的子项目,而不会导致它们相互干扰。

要使资产路由在您的应用程序中正常工作,您需要更改

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

为以下内容

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

下一步:移除 `GlobalSettings`


发现此文档中的错误?此页面的源代码可以在 此处 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?转到 我们的社区论坛 与社区开始对话。