2013-10-02 61 views
4

我想創建一個只有當客戶端發送特定的Accept標題時才匹配的路由。我使用Spray 1.2-20130822如何匹配路由中的特定接受標頭?

我想獲得的路由工作:

def receive = runRoute { 
    get { 
     path("") { 
     accept("application/json") { 
      complete(...) 
     } 
     } 
    } 
    } 

Here我發現使用accept()功能的規範,但我無法弄清楚如何在我的噴霧處理程序導入,使其工作作爲指令。另外,我沒有在標題指令中找到其他doc,但是這些stubs

回答

5

我會做這樣的:

def acceptOnly(mr: MediaRange*): Directive0 = 
    extract(_.request.headers).flatMap[HNil] { 
    case headers if headers.contains(Accept(mr)) ⇒ pass 
    case _          ⇒ reject(MalformedHeaderRejection("Accept", s"Only the following media types are supported: ${mr.mkString(", ")}")) 
    } & cancelAllRejections(ofType[MalformedHeaderRejection]) 

然後,只需換根:

path("") { 
    get { 
    acceptOnly(`application/json`) { 
     session { creds ⇒ 
     complete(html.page(creds)) 
     } 
    } 
    } 
} 

順便說一下最新的噴霧1.2夜間是1.2-20130928如果可以的話,更新

+0

這裏有一個小錯誤:如果傳入多個'MediaRange'並且它們中的任何一個都不匹配,則'$ {mr:_ *}'的字符串插值失敗。如果我將它更改爲'$ {mr}',它會運行,儘管輸出包含現在可能不適用的'mr'類型。 – rompetroll

+2

@rompetroll對不起,不知道,謝謝。你可以用'$ {mr.mkString(「,」)}替換'$ {mr:_ *}' – 4lex1v

2

沒有預先定義的指令,稱爲accept指令。您可以看到可用指令的完整列表here

但是,您可以使用headerValueByName指令做出一個自定義的指令,做你的願望:

def accept(required: String) = headerValueByName("Accept").flatMap { 
    case actual if actual.split(",").contains(required) => pass 
    case _ => reject(MalformedHeaderRejection("Accept", "Accept must be equal to " + required)) 
} 

將這個代碼在你噴Route的範圍,那麼就用你在你的問題顯示。

+2

謝謝你應該工作。儘管如果actual.split(「,」)包含required或者類似的話,我可能應該將'if actual == required'改成''。 – rompetroll