文件

§前言

在深入了解此版本的重點之前,我們強烈建議您熟悉下列主題,因為這些主題可能會與您使用 Play Framework 進行業務相關

我們還要請您注意,我們目前正在尋找額外的白金贊助商。如果您的公司有足夠的財力擔任此角色,我們將非常感謝您與我們聯繫。更多詳細資訊請見此處

最後但並非最不重要的是,我們要向所有我們的 高級贊助商和所有個人 表達我們衷心的感謝,無論是現在還是過去,他們的慷慨捐助讓我們得以繼續開發 Play Framework。
沒有您的支持,這個版本永遠不會發生!

§Play 2.9 的新功能

本節重點介紹 Play 2.9 的新功能。如果您想了解在遷移到 Play 2.9 時需要進行的變更,請查看 Play 2.9 遷移指南

此頁面也適用於 Play 3.0,它包含與同時發布的 Play 2.9 相同的新功能和錯誤修正。唯一的區別是 Play 2.9 建構於 Akka 和 Akka HTTP,而 Play 3.0 建構於 Pekko 和 Pekko HTTP。如果您想在遷移到 Play 2.9 後繼續使用 Pekko 遷移到 Play 3.0,請參閱 Play 3.0 遷移指南

§Scala 3 支援

Play 2.9 提供 Scala 3 人工製品!您現在可以使用 Play 搭配 Scala 3.3.1 或更新版本。請注意,不支援 3.0 到 3.2 的 Scala 版本。請注意,需要某些遷移步驟。如需全面指南,請參閱 Scala 3 遷移指南

重要的是要強調,Play 僅支援 Scala LTS(長期支援) 版本。因此,Scala 3.3 LTS 和後續 LTS 版本之間的任何 Scala 發行版本都不會受到 Play 的官方支援。但是,仍然有可能使用 Play 搭配此類 Scala 版本。

沒有立即將您的 Play 應用程式轉換到 Scala 3 的壓力,因為 Scala 2.13 仍在維護中,我們預計未來許多年的 Scala 2.13 發行版本。儘管如此,明智的做法是在您的未來路線圖中開始考慮升級您的應用程式。

根據您的程式碼庫,將現有的 Play 應用程式移轉到 Scala 3 可能是一項龐大的任務。我們強烈建議您先移轉到 Play 2.9,同時保留 Scala 2.13。此方法可確保所有功能都能如預期般運作。之後,您可以轉換到 Scala 3。

§Java 17 和 21 支援

Play 2.9 是第一個提供現成支援 Java 21 LTS 和 Java 17 LTS 的主要版本。雖然已經可以將 Java 17 與 Play 2.8.15 一起使用,這仍然需要一些調整

升級到 Play 2.9 時,我們強烈建議考慮至少升級到 Java 17 LTS。值得注意的是,在即將推出的 Play 2.x 版本(版本 2.10)中,我們可能會停止支援 Java 11。我們做出此建議的決定是基於 Play 所依賴的函式庫已停止提供 Java 11 工件的事實。因此,我們希望避免在未來遇到安全性問題,因為我們可能無法升級這些依賴項。此外,您可能對我們在 Play 2.9 發布之前使用TechEmpower 的 Framework Benchmarks 組合進行的本地效能評量感興趣:結果顯示,僅升級到 Java 17 就能提升效能,進而提升應用程式的效能。

請注意,在 Java 17 和 Java 21 中使用自簽憑證繫結 HTTPS 埠可能會導致問題。有關此問題的更多詳細資訊,請參閱 Play 2.9 移轉指南中的"在 Java 17 和 Java 21 中產生自簽憑證會失敗"

Play、其獨立模組、範例和種子專案都經過嚴格測試,以符合OpenJDK Temurin版本 11、17 和 21。

Play 僅支援 Java LTS 版本。因此,Java 21 LTS 與後續 LTS 之間的任何 Java 版本,即使仍有可能使用 Play 搭配此類版本,也不會獲得 Play 的官方支援。

§Scala 2.12、sbt 0.13 和 Java 8 支援已終止

除了 Scala 2.12 之外,我們選擇在此版本中終止對 Java 8 的支援。此決定是基於 Play 所依賴的函式庫數量越來越多,而這些函式庫已停止提供 Java 8 人工製品。此外,Play 2.9 已正式終止對 sbt 0.13 的支援。儘管 Play 可能仍與各種 sbt 1.x 版本相容,但我們的官方支援已延伸至 sbt 版本 1.9.6 或更新版本。因此,我們強烈建議您使用 最新可用的 sbt 版本 來維護您的設定。

§Akka HTTP 10.2

儘管 Play 2.9 繼續使用 Akka 2.6,但它已升級到 Akka HTTP 10.2,這是從 10.1 升級而來的。請務必注意,Play 2.9 將維護這些版本,而不會超出這些版本。此決定是基於 Akka 2.6 和 Akka HTTP 10.2 是仍受 Apache 授權規範的最終版本。後續的 Akka 版本受 BSL 約束,而 Play 故意避免使用 BSL。我們強烈建議您檢閱

§Guice 升級至版本 6

Play 使用的預設依賴注入架構 Guice 已升級至版本 6.0.0(從 4.2.3 升級)。請參閱 5.0.15.1.06.0.0 發行說明以取得更多詳細資訊。如 Guice 6 發行說明中所述,您可以繼續使用 javax.inject 名稱空間。或者,如果您願意,也可以選擇切換至 jakarta.inject

值得注意的是,在 Play 的下一個主要版本中,我們將升級到 Guice 7,它不再支援 javax.inject

§Jackson 升級至 2.14

Jackson 已收到期待已久的更新,版本超過 2.11。在 Play 2.9 中,預設的 Jackson 版本為 2.14,即使已有更新的版本可用。此決定主要受到 Akka 和更廣泛的相容性環境影響。Akka 和 Pekko 尚未升級到這些更新的 Jackson 版本,我們希望避免與這些關鍵元件相容性中斷的潛在風險。但是,如果您願意,您可以按照 這裡 所述的方式升級到更新的版本。

§轉換至 Jakarta Persistence

從 Java Persistence API 轉換到 Jakarta Persistence API,現在支援 Hibernate 6 和更新版本,以及 EclipseLink 3 和更新版本。請參閱對應的 遷移指南,以取得有關將 Hibernate 或 EclipseLink 升級到新命名空間的詳細說明。

§升級 sbt-web 和 sbt-js-engine

sbt-websbt-js-engine 已進行重大重構,帶來多項顯著改進

sbt-web 已 移除其對 Akka 的依賴,簡化了兩個程式碼庫,並作為有益的副作用,解決了記憶體外洩問題。先前獨立的專案 npmjs-engine 已整合到 sbt-js-engine 中。

從 Play 附帶的版本 1.3.0 開始,sbt-js-engine 會嘗試偵測系統的 npm 指令,當使用支援 Node.js 的本地安裝 js 引擎時。它會使用系統的 npm,而不是過時的 npm webjars,它不支援更新的 npm 指令。此行為現在是預設行為,可以使用 npmPreferSystemInstalledNpm := false 停用。此設定可確保 webjar npm 會在不論使用哪個引擎的情況下使用。

此外,從版本 1.3.0 開始,可以透過設定 `npmSubcommand := NpmSubcommand.Install` 來指定要使用的 `npm` 子指令(可用的選項包括 `Install`、`Ci` 和 `Update`,後者為預設值)。

§HikariCP 升級

HikariCP 是 Play 的預設 JDBC 連線池,已升級至版本 5。您可以檢閱 變更記錄 以取得此版本的詳細資訊。此升級讓我們可以引入新的設定選項:`play.db.prototype.hikaricp.keepaliveTime`(或特定資料庫的 `db.default.hikaricp.keepaliveTime`,例如 `default`)。此設定接受持續時間值,例如 `1 minute`。

有關此設定的更完整資訊,請參閱 HikariCP GitHub README

§其他新增功能

§結果屬性

與要求屬性類似,Play 現在支援結果屬性。這些屬性以相同的方式運作,讓您可以在結果物件中儲存額外資訊以供未來存取。在利用動作組合或篩選器時,此功能特別有用。由於方法與用於要求屬性的方法相同,您可以參閱 要求屬性運作方式,並對結果物件套用類似的方法。

§延遲主體剖析

預設情況下,主體剖析會在透過動作組合定義的動作處理之前執行。現在可以變更此順序。有關為何以及如何變更此順序的詳細資訊,請參閱 JavaScala 文件。

§動作組合中包含 WebSocket 動作方法

使用 Play Java 時,請考慮下列利用 動作組合 的控制器範例

@Security.Authenticated
public class HomeController extends Controller {

    @Restrict({ @Group({"admin"}) })
    public WebSocket socket() {
        return WebSocket.Text.acceptOrResult(request -> /* ... */);
    }
}

先前,在處理 WebSocket(例如上面顯示的 socket() 方法)時,並未套用動作組合。因此,來自 Deadbolt 2 函式庫 的註解(例如 @Security.Authenticated@Restrict)沒有任何作用,且從未執行。Java WebSocket 文件建議使用 acceptOrResult 方法來檢查使用者權限等。

從 Play 2.9 開始,您現在可以啟用新推出的設定選項 play.http.actionComposition.includeWebSocketActions,方法是將其設定為 true。將 WebSocket 動作方法納入動作組合中,可確保註解為 @Security.Authenticated@Restrict 的動作現在會如預期般執行。這種方法的優點是,您可能不需要在 acceptOrResult 方法中複製註解動作方法中已實作的驗證或授權程式碼。

§可設定的演化腳本位置

現在可以使用新的 play.evolutions[.db.default].path 設定自訂演化腳本的位置。這可讓您將演化腳本儲存在 Play 專案中的特定位置,甚至可以使用絕對或相對路徑將其儲存在專案根資料夾外部。如需完整資訊,請參閱 演化文件

§演化腳本中的變數替換

演化腳本現在支援在 application.conf 中定義的對應值替換的佔位符

play.evolutions.db.default.substitutions.mappings = {
  table = "users"
  name = "John"
}

例如,類似這樣的演化腳本

INSERT INTO $evolutions{{{table}}}(username) VALUES ('$evolutions{{{name}}}');

將會轉換成

INSERT INTO users(username) VALUES ('John');

在演化應用程式處理期間。

注意:evolutions meta 表格保留原始 SQL 程式碼,取代佔位符。

meta 表格預設名稱為 play_evolutions。您可以透過設定 play.evolutions.db.default.metaTable 來修改。

變數替換不區分大小寫。因此,$evolutions{{{NAME}}} 等於 $evolutions{{{name}}}

您也可以修改佔位符語法的字首和字尾

# Change syntax to @{...}
play.evolutions.db.default.substitutions.prefix = "@{"
play.evolutions.db.default.substitutions.suffix = "}"

evolution 模組支援一個逃逸機制,用於不應替換變數的情況。此機制預設啟用。若要停用,請設定

play.evolutions.db.default.substitutions.escapeEnabled = false

啟用時,!$evolutions{{{...}}} 可用於逃逸變數替換。例如

INSERT INTO notes(comment) VALUES ('!$evolutions{{{comment}}}');

不會以其替換取代,而是會變成

INSERT INTO notes(comment) VALUES ('$evolutions{{{comment}}}');

在最終 SQL 中。

此逃逸機制適用於所有 !$evolutions{{{...}}} 佔位符,無論是否在 substitutions.mappings 設定中定義了變數對應。

§Evolution Meta 資料表的自訂命名

現在可以為每個資料來源重新命名 play_evolutions meta 資料表。例如,如果您希望將 default 資料來源的 meta 表格命名為 migrations,請設定下列設定

play.evolutions.db.default.metaTable = "migrations"

如果您透過 useLocks 設定使用鎖定表格,則鎖定表格也會與您的 evolution meta 資料表同名,並加上 _lock 字尾(migrations_lock 取代 play_evolutions_lock)。有關更多資訊,請參閱 Evolutions 文件。

如果您打算在現有的 Play 應用程式中使用此功能,請在設定之前手動重新命名 meta 表格。

§允許檔案上傳為空主體或空檔名

現在您可以設定

play.http.parser.allowEmptyFile = true

允許空的 multipart/form-data 檔案上傳,無論檔案名稱或檔案本身是否為空。預設情況下,此組態設定為 false

§包含其他錯誤資訊的請求屬性

在錯誤處理程式中,您現在可以存取「http 錯誤資訊」請求屬性(如果可用)。此屬性包含有助於錯誤處理的補充資訊。目前,您可以取得錯誤處理程式最初被呼叫的位置詳細資料

Java
request.attrs.getOptional(play.http.HttpErrorHandler.Attrs.HTTP_ERROR_INFO).map(info => info.origin()).orElse("<unknown error origin>")
Scala
request.attrs.get(play.api.http.HttpErrorHandler.Attrs.HttpErrorInfo).map(_.origin).getOrElse("<unknown error origin>")

目前,Play 2.9 會根據錯誤處理程式的來源提供下列值

第三方模組可能會引入自己的來源。此外,未來的 Play 版本可能會包含更多與錯誤相關的資訊。

§CORS 篩選器支援 * 萬用字元

CORS 篩選器的 allowedOrigins 組態現在接受萬用字元 *,它具有特殊意義。如果請求來源與清單中的任何其他來源都不相符,將會傳送 Access-Control-Allow-Origin: *

play.filters.cors.allowedOrigins = ["*"]

如需更多詳細資料,請參閱 CORS 篩選器文件

§新的 IP 篩選器

已新增一個新的篩選器來透過黑名單或白名單 IP 位址來限制存取。有關詳細資訊,請參閱 IP 篩選器頁面

§Play-Configuration 專案作為獨立函式庫

封裝 Typesafe Config 的 Play play.api.Configuration 類別現在可以使用為獨立函式庫。我們的目標是讓它的佔用空間降至最低。除了 Typesafe Config 之外,它只依賴於 slf4j-api 進行記錄,以及 Play 的 play-exceptions 專案,其中包含 Play 本身和 Play SBT 外掛程式所需的兩個例外類別。

要使用此函式庫,請將其加入任何 Scala 專案,方法是在 build.sbt 中包含它

libraryDependencies += "com.typesafe.play" %% "play-configuration" % "<PLAY_VERSION>"

§新增 UUID PathBindableExtractor

路由 DSL 現在包含開箱即用的 UUID 繫結功能。

§新的伺服器後端組態金鑰

若要全面了解這些新組態的功能,請參閱 Akka HTTPNetty 伺服器後端組態頁面,以及有關如何「優雅地關閉伺服器」的文件。

§增強的建置基礎架構

順帶一提,我們想通知您,我們已將 GitHub Play Framework 組織下的所有儲存庫從 Travis CI 轉移到 GitHub Actions。根據我們的經驗,GitHub Actions 已證明更可靠、速度顯著提升,且由於與 GitHub 的無縫整合而更容易維護。我們要感謝 Sergey Morgunov 在促成此遷移中所做的傑出工作。他在建立出色的 可重複使用的 GitHub 工作流程 上投入了大量時間。

感謝 sbt-ci-release,我們簡化了發布新版本的流程。現在,我們只需將 git 標籤推送到 GitHub,即可產生新版本。這消除了在開發人員機器上本地發布人工製品時可能發生的錯誤的疑慮,而這種情況在過去經常發生。

切換到現在在 Scala 開發人員社群中相當普遍的助手,有助於我們更順利且快速地發佈更新函式庫的新版本。儘管這些工具廣受認可,我們還是想藉此機會肯定它們的重要性。我們由衷感謝 Scala StewardRelease Drafter 等工具的建立者和維護者,以及其他人的傑出貢獻。他們的努力在讓我們持續提供 Play 方面扮演著至關重要的角色。

§Play 2.10 / Play 3.1 的計畫

我們想提供 Play 2.10 / Play 3.1 中我們計畫納入內容的初步概觀,讓您可以開始考慮這些變更

當然,此清單並非詳盡無遺。您可以透過我們的 GitHub 路線圖Play 2.10 里程碑 追蹤我們的計畫。

下一步:移轉指南


在此文件發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提交拉取請求。有問題或建議要分享嗎?前往 我們的社群論壇 與社群展開對話。