java - Play Framework 2 - 调用 Web 服务并返回一个对象

标签 java playframework-2.0

我有一个模型,我想用网络服务的详细信息填充它。我想异步执行此操作,以免阻塞服务器线程。让我们假设它是一个登录服务。

现在我要做的是向远程服务器发出请求并最终返回一个用户模型对象。所以方法签名看起来像这样:

public static User loginUser(String username, String password) {

我知道要对 Web 服务进行异步调用,我应该使用 Promise:

Promise<WS.Response> wsPromise = WS.url("http://myserver.com/login")
            .setContentType("application/json; charset=utf-8")
            .post("... the username and password ...");

还没有开始请求。我可以对该对象调用 get() 以对服务进行阻塞调用。这行得通。

要异步执行此操作,我认为我需要映射它并以某种方式执行它。

Promise<User> resultPromise = wsPromise.map(new F.Function<WS.Response, User>() {
    @Override
    public User apply(WS.Response response) throws Throwable {
        System.out.println(response.getBody());
        return new User(... based on something extracted from the returned JSON ...);
    }
});

现在我该如何触发这个操作?如果我在 resultPromise 上调用 get(),它会进行调用但最终会触发超时异常。我不能使用 async(...) 方法,因为它只会返回一个 Result

查看其他示例 ( https://github.com/jroper/play-promise-presentation/blob/master/src/main/java/controllers/Application.java ),这似乎是模式。也就是说,我们总是想返回一个 Result 对象。但是,我无法查询 Result 对象,而且我没有计划将该特定对象发送给用户。

事实上,这些示例似乎调用了一个网络服务,将 JSON 结果映射到一个对象,然后立即将它们映射回相同的 JSON。当我想将用户(在我的例子中)传递回调用函数时没有多大用处。

老实说,无论如何我对它的异步性质有点困惑(您可能已经猜到了)。特别是,这实际上是一个阻塞操作,因为我们必须等待 Web 服务返回响应。该文档似乎表明使用 Promise/Future 模式将避免这种阻塞。

底线是:如何在不阻塞 Play Framework 服务器线程的情况下将 Web 服务调用的结果映射回模型对象?

随意滥用我对 Play Framework 缺乏经验...

最佳答案

这个答案可能来得太晚了,但会发布它以防现在其他人仍然想知道同样的问题并希望得到问题的答案。

有两种方法可以实现这一点,尽管它们都使用相同的 JsonNode。类:

  1. 第一个是您所期望的:“新用户(..something...)”

在这种情况下,您可以使用 JsonNode 的“get”方法来获取创建用户对象所需的特定数据(在我的示例中为用户名和电子邮件,因为您没有指定必填字段)。

Promise<User> resultPromise = wsPromise.map(new F.Function<WS.Response, User>() {
    @Override
    public User apply(WS.Response response) throws Throwable {
        System.out.println(response.getBody());
        JsonNode json = response.asJson();
        return new User(json.get("username"), json.get("email"));
    }
});
  1. 另一种选择是在您知道 Web 服务确实返回用户对象的有效 Json 表示形式的情况下。

我个人认为这个选项更简单并且依赖于 fromJson's method from Json类。

Promise<User> resultPromise = wsPromise.map(new F.Function<WS.Response, User>() {
    @Override
    public User apply(WS.Response response) throws Throwable {
        System.out.println(response.getBody());
        return Json.fromJson(response.asJson(), User.class);
    }
});

我希望这个答案可以帮助那些想知道如何以简单的方式做到这一点的人。

关于java - Play Framework 2 - 调用 Web 服务并返回一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17095935/

相关文章:

java - 在gradle添加时项目之间的循环引用

playframework - Play 框架中的 Assets 指纹识别

scala - Play Scala 激活器编译命令显示值 userid 不是 play.api.data.Form[models.Changepas sword] 的成员

scala - 如何转换 Play ! 2.0 Scala文件转换为CSVReader格式?

java - 使用 com.google.code.gson 在 Java8 中创建 JSON 对象

selenium - HTMLUNIT 驱动程序 : The data necessary to complete this operation is not yet available

java - 将多个项目导出为 jar

java - 根据 json 中的 ID 对 fragment 中的项目进行排序

java - 拦截方法调用并添加/丰富参数

java - 在 headless 模式下渲染 Swing 容器