2013-10-02 6 views
4

Я хочу создать маршрут, который соответствует только если клиент отправляет конкретный заголовок Accept. Я использую Spray 1.2-20130822.Как сопоставить конкретные заголовки принятия в маршруте?

Я хотел бы получить маршрут работы:

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

Here я нашел спецификацию, используя accept() функцию, но я не могу понять, что импортировать в моем Spray-обработчиком, чтобы заставить его работать как директива. Кроме того, я не нашел других документов для заголовков, но эти 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

Крошечная ошибка здесь: интерполяция строк '$ {mr: _ *}' не выполняется, если передано более одного 'MediaRange', и ни одна из них не сопоставляется. Если я изменил это на '$ {mr}', он запускается, хотя на выходе содержится тип 'mr', который, вероятно, не предназначен. – rompetroll

+2

@rompetroll Извините, не знал этого, спасибо. Вы можете заменить '$ {mr: _ *}' на '$ {mr.mkString (", ")}' – 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

Благодарю вас, что вы должны работать. Хотя я, вероятно, должен изменить 'if actual == required'', если actual.split (",") содержит требуемый' или что-то в этом роде. – rompetroll