how to extract the (json) string out of a (Akka-http) RequestEntity

4248 views
Skip to first unread message

Robin Bakkerus

unread,
Jan 16, 2015, 8:26:48 AM1/16/15
to akka...@googlegroups.com
Can some one help me with (I think) a very simply question, but one I could not figure out myself yet.

It is about how extract the (json) string out of the RequestEntity, inside a HttpRequest

From the command line I give a command like this:
curl -i -H "Accept: application/json" -H "Content-Type:application/json" -X POST --data '{"value":{"id":1}' http://localhost:8000/saveTsta

And this should be handled by an Akka-http server like this:

 def requestHandler(req: HttpRequest): Future[HttpResponse] = req match {
    case HttpRequest(POST, Uri.Path("/saveTsta"), _, _, _)    => saveTsta(req)
    case _: HttpRequest                                       => unknownReq(req)
  }


def saveTsta(req: HttpRequest): Future[HttpResponse] = {
    val entity:RequestEntity = req.entity
    
    val json:String = how_do_get_the_json_data_out_of(entity) ???
}

Txs in advance

Ian Holsman

unread,
Jan 16, 2015, 6:49:49 PM1/16/15
to Akka User
I'm not saying this is the best way..

val postDataF: Future[ByteString] =
entity.dataBytes.fold(ByteString("")) { (z, i) => z.concat(i)}
val postData: String = Await.result(postDataF, 50.millis).decodeString("UTF-8")
> --
>>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>>> Check the FAQ:
>>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> ---
> You received this message because you are subscribed to the Google Groups
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to akka-user+...@googlegroups.com.
> To post to this group, send email to akka...@googlegroups.com.
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.



--
Ian Holsman
i...@holsman.com.au
PH: + 61-3-9028 8133 / +1-(425) 998-7083

Robin Bakkerus

unread,
Jan 17, 2015, 1:56:17 AM1/17/15
to akka...@googlegroups.com
Txs Ian, your solution works but now I am running into another problem. In the result string all quotes are lost!

In my earlier post, I only included a very small porting of the cmd-line. In practice this cmd line looks more like this:
curl -i -H "Accept: application/json" -H "Content-Type:application/json" -X POST --data '{"value":{"id":null,"ofd":null,"name":"VSKkD","count":4981,"flag":false}'

after running your code, println(postDate) gives:
'{value:{id:null,ofd:null,name:VSKkD,count:4981,flag:false}'

Any idea how to extract the origial json string ?


Op zaterdag 17 januari 2015 00:49:49 UTC+1 schreef Ian Holsman:

Mohamed Ragab

unread,
Mar 22, 2015, 3:34:58 AM3/22/15
to akka...@googlegroups.com
Again, not necessarily the best solution but ..

Note: Some of the code here is in Java, so you will need to do some digging/translation

Modifying the akka.http.marshallers.jackson.Jackson (Scala)
(possibly creating your own copy with the modifications)

Adding the following

def jsonAsString(): Unmarshaller[String] =
UnmarshallerImpl[String] { (_ec, _flowMaterializer) ⇒
implicit val ec = _ec
implicit val mat = _flowMaterializer
unmarshalling.Unmarshaller.messageUnmarshallerFromEntityUnmarshaller { // isn't implicitly inferred for unknown reasons
unmarshalling.Unmarshaller.stringUnmarshaller
.forContentTypes(`application/json`)
}
}(ClassTag(classOf[String]))


You can then use the RequestVal (java)

RequestVal<String> jsonStringExtractor = RequestVals.entityAs(MyJackson.jsonAsString());

To extract the JSON String

@Override
public Route createRoute() {
return route(
pathPrefix("jsontest").route(
post(handleWith(stringParser, (ctx, theRequest) -> {
System.out.println("JSON String :: "+theRequest);
return ctx.complete(createHttpResponse("OK"));
})))
);


Hope this helps, feedback is more than welcome

--
Mohamed

Mark Hatton

unread,
Mar 24, 2015, 9:52:37 AM3/24/15
to akka...@googlegroups.com
Hi Robin,

Have you considered using an Akka HTTP route (akin to a spray route)?  E.g.:

val route = path("saveTsta")(
  post(
    entity(as[String]){
      json =>
        System.out.println(json)
        complete(StatusCodes.OK)
    }
  )
)

Complete gist: https://gist.github.com/markhatton/17b586982f1beab30425

Mark

Phillip Taylor

unread,
May 2, 2020, 2:19:56 AM5/2/20
to Akka User List

Not only does this answer require you to have the appropriate json libraries to map from a JObject back to a string  - It can be subtly broken in that its doing String -> Json representation -> String transformation, ergo, nulls and nones, whitespace and other changes are all subject to be misrepresented compared to what was genuinely posted to the service. Use it with caution.
Reply all
Reply to author
Forward
0 new messages