§Play 2.8 遷移指南
本指南適用於從 Play 2.7 遷移至 Play 2.8。請參閱 Play 2.7 遷移指南 以從 Play 2.6 升級。建議一併閱讀 Akka 2.5 至 2.6 遷移指南,因為其中的多項變更會影響 Play 2.8。
§如何遷移
在啟動 sbt
之前,請務必進行以下升級。
§Play 更新
在 project/plugins.sbt
中更新 Play 版本號碼
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.x")
其中 2.8.x
中的「x」是你想要使用的 Play 次要版本,例如 2.8.0
。
§sbt 升級
雖然 Play 2.8 仍支援 sbt 0.13,但我們建議你使用 sbt 1。這個新版本獲得支援且積極維護。若要更新,請變更你的 project/build.properties
,使其讀取
sbt.version=1.3.10
撰寫本文時,1.3.10
是 sbt 1.x 系列中的最新版本,你可能也能使用較新的版本。查看 Play 次要版本的 發行說明 和 sbt 的 發行說明 以取得詳細資訊。
§API 變更
Play 2.8 包含多項 API 變更。和往常一樣,我們遵循在移除現有 API 之前將其標示為不建議使用的政策。本節說明這些變更。
§SSLEngineProvider 使 SSLContext 可見
在 設定 HTTPS 時,如果你需要完整設定 SSL 憑證,可以覆寫 play.server.SSLEngineProvider
。在 Play 2.8.0 之前,提供者只會使 SSLEngine 可見。現在,為了與第三方程式庫更好地整合,SSLContext 也必須可見。請參閱 ConfiguringHttps 頁面以取得更多詳細資訊。
§Scala 2.11 支援已終止
Play 2.8 支援 Scala 2.12 和 2.13,但不支援已達使用期限的 Scala 2.11。
§在專案中設定 scalaVersion
Scala 和 Java 使用者都必須設定 sbt 以使用 Scala 2.12 或 2.13。即使專案中沒有 Scala 程式碼,Play 本身也會使用 Scala,且必須設定為使用正確的 Scala 函式庫。
若要在 sbt 中設定 Scala 版本,只需設定 scalaVersion
鍵,例如
scalaVersion := "2.13.13"
如果您有一個單一專案建置,則此設定可以單獨放置在 build.sbt
中。但是,如果您有多專案建置,則必須在每個專案中設定 Scala 版本設定。通常,在多專案建置中,您會有一些每個專案共用的設定,這是放置設定的最佳位置,例如
def commonSettings = Seq(
scalaVersion := "2.13.13"
)
val projectA = (project in file("projectA"))
.enablePlugins(PlayJava)
.settings(commonSettings)
val projectB = (project in file("projectB"))
.enablePlugins(PlayJava)
.settings(commonSettings)
§檔案提供方法已變更其 filename
參數的類型
提供檔案的方法,例如 Java API 中的 ok(File content, ...)
(和類似方法)或 Java 的 StatusHeader
和 Scala 的 Status
類別中的 sendFile
、sendPath
和 sendResource
已變更其 filename
參數的類型:Scala API 現在使用 Option[String]
作為其 filename
參數函式的回傳類型,而非使用純文字 String
。Java API 已將參數類型變更為 Optional<String>
。
此 API 變更更能反映以下事實:如果您不希望 Content-Disposition
標頭包含檔案名稱,則可以傳遞 None
/ Optional.empty()
。
§Java API 的 Headers
類別是不可變的
類別 play.mvc.Http.Headers
現在是不可變的。某些方法已棄用,並已替換為新的方法
已棄用的方法 | 新方法 |
---|---|
toMap() |
asMap() |
addHeader(String name, String value) |
adding(String name, String value) |
addHeader(String name, List<String> values) |
adding(String name, List<String> values) |
remove(String name) |
removing(String name) |
請注意,舊的已棄用方法會傳回原始已修改的 Headers
物件,而新方法總是會傳回新的物件,讓原始物件保持不變。
§已棄用的 API 已移除
許多在早期版本中已棄用的 API 已在 Play 2.8 中移除。如果您仍在使用它們,我們建議在升級到 Play 2.8 之前,先移轉到新的 API。請查看 Javadoc 和 Scaladoc 以取得移轉注意事項。另請參閱 Play 2.7 移轉指南 以取得更多資訊。
§Java API
在 Play 2.7 中,我們棄用 play.mvc.Http.Context
,並建議直接使用 play.mvc.Http.RequestHeader
或 play.mvc.Http.Request
。我們現已移除 Http.Context
,如果您的應用程式依賴於它,您應該閱讀 Play 2.7 移轉指南說明。
§快取 API 變更
SyncCacheApi
和AsyncCacheApi
中getOrElseUpdate
方法的Caffeine
實作現在是原子的。(請注意,getOrElseUpdate
方法的 EhCache 實作仍然是非原子的)getOrElseUpdate
方法的Caffeine
實作會延遲評估orElse
部分,這表示如果快取中存在具有給定金鑰的項目,則不會執行orElse
部分play.cache.caffeine.CaffeineDefaultExpiry
類別現已棄用
§組態變更
此區段列出組態中的變更和棄用事項。
§ObjectMapper
序列化變更
Play 2.8 採用 Akka Jackson 序列化支援,並使用 Akka 提供的預設值。其中一項變更為 Java Time 類型的呈現方式。在 Play 2.7 之前,它們會以時間戳記呈現,效能較佳,但現在改用 ISO-8601 (rfc3339) 格式 (yyyy-MM-dd'T'HH:mm:ss.SSSZ
) 呈現。
如果您需要使用舊的時間戳記預設格式,請在 application.conf
中加入下列組態
akka.serialization.jackson.play.serialization-features {
WRITE_DATES_AS_TIMESTAMPS = on
WRITE_DURATIONS_AS_TIMESTAMPS = on
}
Play 提供的 ObjectMapper
執行個體(使用 Json#newDefaultMapper
或 Guice 管理的 play.core.ObjectMapperProvider
)包含 Jackson 解序列化器對 JsonNode
的堆疊效率實作。如果您已使用自訂解序列化器將 json 酬載讀入 JsonNode
,您有兩個選項
- 您可以使用設定從
ObjectMapper
中停用 Play 的play.utils.JacksonJsonNodeModule
akka.serialization.jackson.play {
jackson-modules = ${akka.serialization.jackson.jackson-modules}
## Play's default settings concatenate "akka.serialization.jackson.jackson-modules"
## with "play.utils.JacksonJsonNodeModule"
## jackson-modules = ${akka.serialization.jackson.jackson-modules} ["play.utils.JacksonJsonNodeModule"]
}
- 您可以進一步完全停用將
ObjectMapper
繫結至Provider<ObjectMapper>
的play.core.ObjectMapperModule
Guice 模組。接著,您必須建立自己的com.example.ObjectMapperModule
並提供該繫結。
theObjectMapper
to aProvider<ObjectMapper>
. Then, you will have to create your
owncom.example.ObjectMapperModule
and provide that binding.
play.modules.disabled += "play.core.ObjectMapperModule"
play.modules.enabled += "com.example.ObjectMapperModule"
§已移除 akka.actor.default-dispatcher.fork-join-executor
的覆寫
Play 在 akka.actor.default-dispatcher.fork-join-executor
中的覆寫已移除,改用 Akka 新且進步的預設值。
請參閱 Akka 遷移指南中與 預設派送變更 相關的區段,以取得更多詳細資料。
§IOSource
和 FileIO
在 Akka Streams 中的變更
與 Akka Streams 如何處理 FileIO.toPath
、StreamConverters.fromInputStream
和 StreamConverters.fromOutputStream
的錯誤相關的變更。請參閱 Akka 移轉指南中與 這些變更 相關的部分,以取得更多詳細資料。
§組態載入變更
在 Play 2.7 之前,當載入組態時,如果使用者提供一些屬性,Play 就不會考慮預設的 Java 系統屬性。現在,系統屬性總是會被考慮,這表示即使您也在定義自訂屬性,您也可以在 application.conf
檔案中參照它們。例如,當 嵌入 Play 時,就像底下的程式碼一樣,userProperties
和系統屬性都會被使用
import java.util.Properties
import play.api.mvc.Results
import play.core.server.AkkaHttpServer
import play.core.server.ServerConfig
import play.api.routing.sird._
class MyApp {
def main(args: Array[String]): Unit = {
// Define some user properties here
val userProperties = new Properties()
userProperties.setProperty("my.property", "some value")
val serverConfig = ServerConfig(properties = userProperties)
val server = AkkaHttpServer.fromRouterWithComponents(serverConfig) { components => {
case GET(p"/hello") => components.defaultActionBuilder {
Results.Ok
}
}}
}
}
請記住,系統屬性會覆寫使用者定義的屬性。
§除錯 SSL 連線
在 Play 2.7 之前,Play 和 Play-WS 都使用 ssl-config 的版本,而該版本具有依賴於未記錄的內部 JSSE 除錯設定修改的除錯系統。這些通常會在啟動時使用 javax.net.debug
和 java.security.debug
系統屬性設定。
除錯系統已移除,而沒有在新系統中直接相關性的除錯旗標已棄用,而新的組態已記錄在 ssl-config 文件 中。
§I18n 行為變更
語言行為的比對現在符合 RFC 4647。
§範例
conf/application.conf
檔案
play.i18n.langs = [ "fr", "fr-FR", "en", "en-US" ]
使用者的接受語言
en-GB
§之前
使用者的接受語言en-GB
與任何設定檔不符。Play 應用程式回應法文頁面,與使用者的意願相違。
§之後
使用者的接受語言en-GB
與en
相符。Play 應用程式回應英文頁面。
§概括的伺服器後端設定檔
Play 附帶兩個伺服器後端
到目前為止,我們將這些設定檔分開,即使有些設定套用於兩個後端,因此是完全的重複。
在 Play 2.8 中,我們開始概括此類重複的伺服器後端設定檔,並將它們直接移至play.server.*
下方
play.server.akka.max-content-length
現已不建議使用。它已移至play.server.max-content-length
。從 Play 2.8 開始,Netty 伺服器後端現在也會遵循該設定檔。play.server.akka.max-header-value-length
和play.server.netty.maxHeaderSize
現在都不建議使用。這些設定檔已移至play.server.max-header-size
。
§重新導向 HTTPS 篩選器的excludePaths
設定檔已變更
現在,重新導向 HTTPS 篩選器的play.filters.https.excludePaths
設定檔包含路徑清單,而非 URI。這表示查詢參數不再重要。如果清單包含/foo
,則要求/foo?abc=xyz
現在也會被排除。在 Play 2.8 之前,由於會根據清單檢查要求的 URI(路徑 + 查詢參數),因此您需要新增完全一個要求的 URI 才能將其從重新導向中排除。
§預設值變更
Play 使用的一些預設值已變更,這可能會對您的應用程式造成影響。本節說明預設變更的詳細資訊。
§提供檔案時不再傳送Content-Disposition: inline
標頭
透過 Scala API 或 Java API 提供檔案時,Play 預設會自動產生 Content-Disposition
標頭並將其傳送給客戶端。
不過,從 Play 2.8 開始,如果計算出的標頭最終完全是 Content-Disposition: inline
(傳遞 inline = true
,這是預設值,以及 null
作為檔案名稱),Play 將不再自動傳送該標頭。這是因為根據 RFC 6266 第 4.2 節,預設會內嵌呈現內容。
因此,此變更不應對您造成任何影響,因為所有瀏覽器都遵守規格,不會對此標頭做任何特殊處理,而是會像未傳送標頭一樣內嵌呈現內容。
不過,如果您仍想傳送此確切標頭,您可以使用 Scala
或 Java
Result
類別的 withHeader(s)
方法。
§相依性圖表變更
在 Play 2.7.0 之前,"com.typesafe.play" %% "play-test"
artifact 包含 Akka HTTP 和 Netty 伺服器後端。這會為您的測試建立不穩定的行為,也可能會讓它們使用與製作程式碼不同的伺服器,具體取決於類別路徑的排序方式。在 Play 2.8 中,play-test
改為依賴於 play-server
,然後測試將使用應用程式使用的相同伺服器提供者。如果您出於某種原因需要將提供者新增到我們的測試,您可以透過將 Akka HTTP 或 Netty 伺服器相依性新增為 "test"
相依性來執行此操作。例如
libraryDependencies += akkaHttpServer % "test" // Use nettyServer if you want the Netty Server backend
§更新的函式庫
除了更新我們自己的函式庫(play-json、play-ws、twirl、cachecontrol 等)的新版本之外,許多其他重要的相依性也更新到最新版本
- specs2 4.8.1
- Jackson 2.10.1
- Mockito 3.2.0
- HikariCP 3.4.1
- Hibernate Validator 6.1.0.Final
- Lightbend Config 1.4.0
- Caffeine 2.8.0
- sbt-native-packager 1.5.1
下一頁:Play 2.7
在此文件檔中發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件檔指南 後,請隨時貢獻一個 pull request。有問題或建議要分享嗎?請前往 我們的社群論壇 與社群展開對話。