Запросить Content-Type в Play! Фреймворк для веб-сервисов REST - PullRequest
5 голосов
/ 13 марта 2012

Я пытаюсь внедрить веб-сервис REST с помощью Play! фреймворк. Я знаю, как вернуть ответ в разных форматах (JSON, XML, HTML, ...), указав несколько шаблонов. Однако я не нашел никакой информации о том, как вы должны обрабатывать различные типы контента в запросе (например, POST) (закодированная форма, JSON, XML, ...).

Можно ли аннотировать метод для соответствия только определенным типам контента (что-то вроде @Consumes)? Должен ли я различать различные типы содержимого запроса с помощью if в методе контроллера?

Ответы [ 3 ]

5 голосов
/ 01 октября 2013

Посмотрите документацию Play для объединения анализаторов тела:

http://www.playframework.com/documentation/2.2.0/ScalaBodyParsers

Если вы хотите ограничить тело сообщения только XML или JSON, вы можете написать что-то вроде этого:

val xmlOrJson = parse.using {
  request =>
    request.contentType.map(_.toLowerCase(Locale.ENGLISH)) match {
      case Some("application/json") | Some("text/json") => play.api.mvc.BodyParsers.parse.json
      case Some("application/xml") | Some("text/xml") => play.api.mvc.BodyParsers.parse.xml
      case _ => play.api.mvc.BodyParsers.parse.error(Future.successful(UnsupportedMediaType("Invalid content type specified")))
    }
}

def test = Action(xmlOrJson) {
  request =>
    request.body match {
      case json: JsObject => Ok(json) //echo back posted json
      case xml: NodeSeq => Ok(xml) //echo back posted XML
    }
}

Функция xmlOrJson просматривает заголовок запроса типа содержимого, чтобы определить анализатор тела. Если это не xml или json, он возвращает анализатор тела ошибки с ответом UnsupportedMediaType (HTTP 415).

Затем вы передаете эту функцию в качестве анализатора тела любого действия, которое хотите ограничить содержимым XML или JSON. В рамках действия вы можете посмотреть на тело, чтобы определить, был ли проанализирован xml или json, и обработать его соответствующим образом.

3 голосов
/ 13 марта 2012

Вы делаете это не через аннотации, а через файл маршрутов или оператор if в своем действии. Зависит от вашего варианта использования, какой из них лучше всего подходит.

Следующий URL-адрес дает некоторую информацию о файле маршрутов для согласования содержимого. http://www.playframework.org/documentation/1.2.4/routes#content-types

Пример

GET    /index.xml         Application.index(format:'xml')  
GET    /index.json        Application.indexJson(format:'json')  

Выше приведены различные действия, но вы можете вызвать одно и то же действие с другим значением формата, если хотите.

0 голосов
/ 22 июня 2016

Вы можете использовать парсер по умолчанию вместе с сопоставлением с образцом в Play 2 с Scala.Как то так:

  def myAction() = Action { req =>
    req.body match {
      case AnyContentAsFormUrlEncoded(m) =>
        val f1 = m.get("field1").flatMap(_.headOption)
        ...
      case AnyContentAsJson(j) =>        
        val f1 = (j \ "field1").asOpt[String]
        ...
      case _ => //handle content types you don't support
        ...
}
...