简体   繁体   中英

How to use MongoDB Async Java Driver in Play Framework 2.x action?

I want to use MongoDB Async Java Driver in a Play Framework 2 project, MongoDB Async Java Driver return SingleResponseCallback. I do not know how to handle this kind of result in Play controllers.

For example how to return count from the following code in a Play controller:

collection.count(
 new SingleResultCallback<Long>() {
  @Override
  public void onResult(final Long count, final Throwable t) {
      System.out.println(count);
  }
});

How can i get result from SingleResultCallback and then convert it to Promise? is it good way? What is the best practice in this situations?

You have to resolve the promise yourself. Remember that the Play promises are wrappers to scala futures and that the only way to resolve a future is using scala Promises (different from play promises) (I know, it's kinda confusing). You'd have to do something like this:

Promise<Long> promise = Promise$.MODULE$.apply();
collection.count(
 new SingleResultCallback<Long>() {
   @Override
   public void onResult(final Long count, final Throwable t) {
     promise.success(count);
  }
});
return F.Promise.wrap(promise.future());

That thing about the Promise$.MODULE$.apply() is just the way to access scala objects from java.

Thanks to @caeus answer, This is the details:

public F.Promise<Result> index() {
    return F.Promise.wrap(calculateCount())
            .map((Long response) -> ok(response.toString()));
}


private Future<Long> calculateCount() {
    Promise<Long> promise = Promise$.MODULE$.apply();

    collection.count(
            new SingleResultCallback<Long>() {
                @Override
                public void onResult(final Long count, final Throwable t) {
                    promise.success(count);
                }
            });

    return promise.future();
}

A cleaner solution would be to use F.RedeemablePromise<A> .

public F.Promise<Result> index() {
    F.RedeemablePromise<Long> promise = F.RedeemablePromise.empty();

    collection.count(new SingleResultCallback<Long>() {
        @Override
        public void onResult(final Long count, final Throwable t) {
            promise.success(count);
        }
    });

    return promise.map((Long response) -> ok(response.toString()));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM