6

我对这个问题中使用的许多概念和技术都很陌生,所以我希望对社区的初学者有一点理解和帮助。我正在使用 Play Framework 2.1.3 版,我需要将数据发布到 RESTful Web 服务,以便可以将其插入远程数据库。将返回一个 XML 响应,指示成功或失败。

我相信您知道 Play Framework 的文档非常缺乏,并且对初学者没有任何帮助,因此我不确定如何在考虑到最佳实践的情况下完成这项任务。我正在寻找这个问题的 Java 解决方案,我目前没有时间学习 Scala 语言。我在 Web 服务方面的经验相当有限,通常我会在我的应用程序中实现 DAO 设计模式(或根据需要使用许多可用的 ORM 库之一)并使用 JDBC 直接连接到数据库。这不是一个选择。

我的第一个问题是,是否有推荐的访问 Web 服务的设计模式?然后,考虑到 Play MVC 框架,如何最好地实现这样的设计模式、打包数据(假设应用程序已经从用户那里捕获并验证了数据)、将其发送出去并处理回给用户的响应?

我知道这是一个相当冗长的问题,但我背后的意图是为初学者创建一个知识库,他们可以轻松地以有限的经验进入,阅读、理解和复制他们在此处找到的内容以产生有效的解决方案。在广泛搜索网络后,我发现了一些不连贯的片段,但没有涉及这些技术的具体内容,也没有最新的教程。感谢您的时间。

4

1 回答 1

11

创建请求很简单。首先,您提供一个 URL。有多种方法可以向请求中添加内容类型、查询参数、超时等。然后,您选择一种请求类型,并可选择添加一些要发送的内容。例子:

WSRequestHolder request = WS.url("http://example.com");
request.setQueryParameter("page", "1");
Promise<Response> promise = request.get();
Promise<Response> promise = WS.url("http://example.com").post(content);

复杂的部分是发送它并使用请求的响应。我假设您有一个控制器,它应该Result根据 Web 服务的响应向用户返回一个。结果通常是一个渲染的模板,或者可能只是一个状态码。

Play 通过使用Futures 和 Promises避免阻塞。控制器的async方法接受 aPromise<Result>并在稍后的某个时间返回结果(未来值)。get上面显示的和post方法提供了一个简单易用的 Promise 。您不需要关心他们的实现,您只需要知道他们承诺Response在请求完成后提供。

WS.url("...").get()请注意这里的问题:使用它创建请求时,Promise<Response>即使async需要Promise<Result>. 在这里,您必须自己实现另一个承诺,它将使用该map方法将响应转换为结果。如果您遵循 Play 文档,这看起来会有些混乱,因为 Java 还没有闭包,并且所有内容都必须包装在一个类中。不过,您不必在方法调用中使用匿名类。如果你喜欢更简洁的代码,你也可以这样做:

return async( 
  request                 
  .get()                   // returns a `Promise<Response>`
  .map(resultFromResponse) // map takes a `Function<Response, Result>` and
                           // returns the `Promise<Result>` we need
);

该对象resultFromResponse可能如下所示。它实际上就像是某种回调方法的繁琐定义,它接受 aResponse作为唯一参数并返回 a Result

Function<Response, List<T>> resultFromResponse = 
    new Function<Response /* 1st parameter type */, Result /* return type */>() {
        @Override
        public Result apply(Response response) {
            // example: read some json from the response
            String message = response.asJson().get("message");
            Result result = ok(message);
            return result;
        }
    };

正如@itsjeyd 在评论中指出的那样,在 Play 2.2.x 中调用 web服务时,您不再包含调用async。您只需返回Promise<Result>

public static Promise<Result> index() {
    return request.get().map(resultFromResponse);
}
于 2013-09-02T18:26:14.500 回答