§內容協商
內容協商是一種機制,可以提供相同資源 (URI) 的不同表示形式。它很有用,例如用於撰寫支援多種輸出格式 (XML、JSON 等) 的 Web 服務。伺服器驅動的協商基本上使用 Accept*
要求標頭執行。您可以在 HTTP 規範 中找到更多關於內容協商的資訊。
§語言
您可以使用 play.api.mvc.RequestHeader#acceptLanguages
方法取得要求中可接受的語言清單,該方法會從 Accept-Language
標頭中擷取語言並根據其品質值進行排序。Play 在 play.api.mvc.Controller#lang
方法中使用它,該方法會提供一個隱含的 play.api.i18n.Lang
值給您的動作,因此它們會自動使用最佳語言(如果您的應用程式支援,否則會使用應用程式的預設語言)。
§內容
類似地,play.api.mvc.RequestHeader#acceptedTypes
方法會提供要求中可接受的結果 MIME 類型的清單。它會從 Accept
要求標頭中擷取類型並根據其品質因子進行排序。
實際上,Accept
標頭並未真正包含 MIME 類型,而是媒體範圍(*例如* 接受所有文字結果的要求可能會設定 text/*
範圍,而 */*
範圍表示可接受所有結果類型)。控制器提供較高層級的 render
方法來協助您處理媒體範圍。例如,請考慮以下動作定義
val list: Action[AnyContent] = Action { implicit request =>
val items = Item.findAll
render {
case Accepts.Html() => Ok(views.html.list(items))
case Accepts.Json() => Ok(Json.toJson(items))
}
}
Accepts.Html()
和 Accepts.Json()
是萃取器,用於測試給定的媒體範圍是否分別符合 text/html
和 application/json
。render
方法會採用從 play.api.http.MediaRange
到 play.api.mvc.Result
的部分函數,並嘗試將其套用至要求 Accept
標頭中找到的每個媒體範圍,依偏好順序。如果您的函數不支援任何可接受的媒體範圍,則會傳回 NotAcceptable
結果。
例如,如果客戶端針對 Accept
標頭提出具有下列值的請求:*/*;q=0.5,application/json
,表示它接受任何結果類型,但偏好 JSON,則上述程式碼會傳回 JSON 表示。如果另一位客戶端針對 Accept
標頭提出具有下列值的請求:application/xml
,表示它只接受 XML,則上述程式碼會傳回 NotAcceptable
。
§要求萃取器
請參閱 play.api.mvc.AcceptExtractors.Accepts
物件的 API 文件,以取得 Play 在 render
方法中預設支援的 MIME 類型清單。您可以使用 play.api.mvc.Accepting
案例類別輕鬆為特定 MIME 類型建立自己的萃取器,例如,以下程式碼建立一個萃取器,用於檢查媒體範圍是否與 audio/mp3
MIME 類型相符
val AcceptsMp3 = Accepting("audio/mp3")
render {
case AcceptsMp3() => ???
}
}
下一步:處理錯誤
在此文件發現錯誤嗎?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件準則 後,請隨時提交 pull request。有問題或建議要分享嗎?請前往 我們的社群論壇 與社群展開對話。