Request a content type in the game! REST Web Services Framework

I am trying to implement a REST web service using Play! framework I know how I can return a response in different formats (JSON, XML, HTML, ...) by specifying several patterns. However, I did not find any information on how you should handle different types of content in the request (e.g. POST) (form encoded, JSON, XML, ...).

Is it possible to annotate a method to match only certain types of content (something like @Consumes)? Should I distinguish between different Content-Types requests with if -clause in the controller method?

+4
source share
3 answers

See the Play documentation for combining body parsers:

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

If you want to limit the message body to xml or json only, you can write something along these lines:

 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 } } 

The xmlOrJson function scans the request header for a content type to determine the body parser. If it is not xml or json, it returns an error body parser with UnsupportedMediaType response (HTTP 415).

You then pass this function as a parser to any action that you want to limit to the contents of xml or json. Inside the action, you can look at the body to determine if xml or json is parsed and processed accordingly.

+4
source

You do not do this through the annotation, but rather through the routes file or through the if statement in your action. Depends on your use case, which is best suited.

The following URL gives you some information about the route file for content negotiation. http://www.playframework.org/documentation/1.2.4/routes#content-types

Example

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

The above calls have different actions, but you can invoke the same action with a different format value if you want.

+3
source

You can use the default parser along with pattern matching in Play 2 using Scala. Something like that:

  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 ... } 
0
source

Source: https://habr.com/ru/post/1401064/


All Articles