我相信您知道Play Framework的文档非常缺乏,对初学者没有任何帮助,因此我不确定如何在考虑最佳实践的情况下完成此任务.我正在寻找这个问题的Java解决方案,我目前没有时间学习Scala语言.我对Web服务的经验相当有限,通常我会在我的应用程序中实现DAO设计模式(或根据需要使用许多可用的ORM库之一)并使用JDBC直接连接到数据库.这不是一个选择.
我的第一个问题是,是否有推荐的访问Web服务的设计模式?然后,考虑到Play MVC框架,如何最好地实现这样的设计模式,打包数据(假设应用程序已经捕获并验证了用户的数据),将其发送出去并将响应处理回用户?
我知道这是一个相当冗长的问题,但我的目的是为初学者创建一个知识库,他们可以轻松地获得有限的经验,阅读,理解和复制他们在这里找到的东西,以产生一个有效的解决方案.在广泛搜索网页后,我发现了一些脱节的片段,但没有具体涉及这些技术,也没有最新的教程.感谢您的时间.
解决方法
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);
复杂的部分是发送它并使用请求的响应.我假设您有一个控制器,应该根据Web服务的响应将结果返回给用户.结果通常是渲染模板或可能只是状态代码.
播放通过使用Futures and Promises来避免阻塞.控制器的异步方法采用Promise< Result>并在稍后的某个时刻返回结果(未来值).上面显示的get和post方法提供了一个简单易用的承诺.您不需要关心它们的实现,只需要知道它们承诺在请求完成后提供响应.
注意这里的问题:当用WS.url(“…”)创建一个请求时,get()会给你一个Promise< Response>即使异步接受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可能如下所示.它实际上就像某种回调方法的繁琐定义,它将Response作为唯一参数并返回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在评论中指出的那样,calling webservices in Play 2.2.x时你不再将该调用包装成异步.您只需返回Promise< Result>:
public static Promise<Result> index() { return request.get().map(resultFromResponse); }