playframework java异步方法调用

时间:2016-04-19 10:17:43

标签: java email asynchronous playframework

playframework 2.2(java 7)

我有REST api接收一些json,json数据我正在做一些事情,最后我发送电子邮件并返回结果。发送电子邮件有点慢,所以 我想在处理json之后在其他线程中调用此电子邮件方法,或者我想执行异步并返回结果而不等待执行电子邮件方法。

如何在控制器中实现和调用异步方法?

以下是代码示例

 public static Result register() {
    JsonNode json = request().body().asJson();
    if (json == null)
        Logger.info("bad json request");
    try {
        RegistrationHandler registrationHandler = new RegistrationHandler();
        if(!registrationHandler.isEmailUnique(json)){
            return ok("false");
        }else{
            registrationHandler.saveUser(json);
            String email = json.findValue("email").asText();
            sendRegistrationEmail(email); // I don't want wait this for execution
            return ok("success");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return ok("error");
}

编辑:

不确定它是否有用,但有效。

 JsonNode json = request().body().asJson();
    if (json == null)
        Logger.info("bad json request");
    try {
        RegistrationHandler registrationHandler = new RegistrationHandler();
        if(!registrationHandler.isEmailUnique(json)){
            return ok("false");
        }else{
            registrationHandler.saveUser(json);
            String email = json.findValue("email").asText();
            F.Promise<java.lang.Boolean> emailPromise = F.Promise.promise(
              new F.Function0<java.lang.Boolean>() {
                public java.lang.Boolean apply() {
                    return sendRegistrationEmail(email);
                }
              }
            );

            return ok("success");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return ok("error");     

2 个答案:

答案 0 :(得分:1)

如果你创建一个Promise来处理JSON检索和处理,你可以附加一个回调来兑换Promise。

此代码基于here的示例。

public static Promise<Result> index() {
    final Promise<SomethingFromJson> eventualObject = WS.url("http://example.com/json")
                                                        .get()
                                                        .map(response -> // do something with the json);

    // add a callback to send mail when the json has been processed
    // this will happen in another thread
    eventualObject.onRedeem(new F.Callback<SomethingFromJson>() {
        // send email
    }, executionContext);

    return eventualObject.map(
        new Function<SomethingFromJson, Result>() {
            public Result apply(SomethingFromJson obj) {
                return ok(// whatever you do with obj);
        } 
      }
    );
}

答案 1 :(得分:1)

我使用了你的代码和示例 https://www.playframework.com/documentation/2.2.x/JavaAsync#Async-results 但我从来没有真正运行过这段代码(也没有编译过)。

重点是你必须返回一个Promise。 Play处理剩下的事情。您可以在调用sendRegistrationEmail(email)的第一个Promise之后返回ok(),但是如果发送错误的话,您将失去发送“错误”的能力。

public static Promise<Result> myMethod() {
    JsonNode json = request().body().asJson();
    if (json == null) {
        Logger.info("bad json request");
        return badRequest();
    }

    RegistrationHandler registrationHandler = new RegistrationHandler();
    if(!registrationHandler.isEmailUnique(json)) {
        return ok("false");
    }

    registrationHandler.saveUser(json);
    String email = json.findValue("email").asText();
    F.Promise<Boolean> emailPromise = F.Promise.promise(
        new F.Function0<Boolean>() {
        public Boolean apply() {
            // This method takes a while
            return sendRegistrationEmail(email);
        }
    });

    return emailPromise.map(new Function<Boolean, Result>() {
        public Result apply(Boolean successful) {
            if (successful) {
                return ok("success");
            } else {
                return ok("error");
            }
        } 
    });
}