【二 HTTP編程】7. 內容協商 原

內容協商

內容協商指對同一URI的不同返回形式。比如說一個同時支持XML、JSON等返回格式的Web Service。服務端驅動的內容協商本質上用Accept* 請求頭實現。HTTP 規範中的內容協商請見這裏

語言

可以用 play.api.mvc.RequestHeader#acceptLanguages 方法從 Accept-Language 頭中獲取支持的語言,並使用 quality 值排序。play.api.mvc.Controller#lang 方法向 action 提供一個implicit play.api.i18n.Lang,以供 Play選擇最佳的適配語言(如果你的應用不支持適配的語言,將使用應用的默認語言)。

內容

類似的,play.api.mvc.RequestHeader#acceptedTypes 方法指明瞭請求可接受result的MIME類型。它會從請求中Accept頭,並按照quality排序。

事實上 Accept 頭包含的是媒體範圍,而不是具體的MIME類型(e.g. 設置 text/* range可以支持所有text result請求,而 */* 將代表支持任意result類型)。Controllers 提供了一個高級的 render 方法來處理媒體範圍。如下例所示:

val list = Action { implicit request => 
    val items = Item.findAll
    render {
        case Accepts.Html() => Ok(view.html.list(items))
        case Accepts.Json() => Ok(Json.toJson(items))
    }
}

Accepts.Html() 和 Accepts.Json() 將嘗試分別匹配指定的 text/html 和 application/json 媒體範圍。render 方法接受一個 play.api.http.MediaRande => play.api.mvc.Result 偏函數,並嘗試使用從Accept頭中的媒體類型來進行模式匹配。如果沒匹配到任意類型,將返回 NotAcceptable。

舉個例子,一個客戶端的Accept頭如下: */*; q=0.5, application/json,表示接受任意的頭但是 application/json 優先,因此上面的代碼段將返回JSON。如果是 application/xml 格式的 Accept Header表示只接受XML,上邊的例子將返回 NotAcceptable。

提取Request

render方法包含的開箱即用MIME類型清單可以參見 play.api.mvc.AcceptExtractors.Accepts對象。你也可以方便的利用 play.api.mvc.Accepting 來創建自己的extractor。下面的例子可用來檢查請求頭是否包含 audio/mp3 MIME類型:

val AcceptsMp3 = Accepting("audio/mp3")
render {
    case AcceptsMp() => ???
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章