How to make a synchronous WS call with Play Framework 2.2 (Java)

心已入冬 提交于 2020-01-02 10:25:09

问题


I'm looking for an example like this but with a synchronous call. My program needs data from external source and should wait until response returns (or until timeout).


回答1:


All you can do is just block the call wait until get response with timeout if you want.

WS.Response response = WS.url(url)
                    .setHeader("Authorization","BASIC base64str")
                    .setContentType("application/json")
                    .post(requestJsonNode)
                    .get(20000); //20 sec

JsonNode resNode = response.asJson();



回答2:


The Play WS library is meant for asynchronous requests and this is good!

Using it ensures that your server is not going to be blocked and wait for some response (your client might be blocked but that is a different topic).

Whenever possible you should always opt for the async WS call. Keep in mind that you still get access to the result of the WS call:

public static Promise<Result> index() {
    final Promise<Result> resultPromise = WS.url(feedUrl).get().map(
            new Function<WS.Response, Result>() {
                public Result apply(WS.Response response) {
                    return ok("Feed title:" + response.asJson().findPath("title"));
                }
            }
    );
    return resultPromise;
}

You just need to handle it a bit differently - you provide a mapping function - basically you are telling Play what to do with the result when it arrives. And then you move on and let Play take care of the rest. Nice, isn't it?


Now, if you really really really want to block, then you would have to use another library to make the synchronous request. There is a sync variant of the Apache HTTP Client - https://hc.apache.org/httpcomponents-client-ga/index.html

I also like the Unirest library (http://unirest.io/java.html) which actually sits on top of the Apache HTTP Client and provides a nicer and cleaner API - you can then do stuff like:

Unirest.post("http://httpbin.org/post")
  .queryString("name", "Mark")
  .field("last", "Polo")
  .asJson()

As both are publically available you can put them as a dependency to your project - by stating this in the build.sbt file.




回答3:


In newer Versions of play, response does ot have an asJson() method anymore. Instead, Jackson (or any other json mapper) must be applied to the body String:

final WSResponse r = ...;
Json.mapper().readValue(r, Type.class)


来源:https://stackoverflow.com/questions/36545751/how-to-make-a-synchronous-ws-call-with-play-framework-2-2-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!