当前位置: 首页 > 知识库问答 >
问题:

playframework java异步方法调用

甘西岭
2023-03-14

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个答案

山高峰
2023-03-14

如果您创建一个promise来处理JSON检索和处理,那么可以在兑现promise时附加一个回调。

此代码基于此处的示例。

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);
        } 
      }
    );
}
鲁鸿
2023-03-14

我在中使用了您的代码和示例https://www.playframework.com/documentation/2.2.x/JavaAsync#Async-结果,但我从未实际运行过此代码(也没有编译)。

关键是你必须回报一个promise。游戏处理其余部分。您可以在第一次promise调用sendRegistrationEmail(email)后返回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");
            }
        } 
    });
}  
 类似资料:
  • 同步调用异步方法最安全的方法是什么?

  • 我正试图从同步方法运行异步方法。但是我不能等待异步方法,因为我在同步方法中。我一定不理解TPL,因为这是我第一次使用它。 每个方法都需要前一个方法来完成,因为第一个方法的数据用于第二个方法。 Await运算符只能在异步方法中使用。考虑用'async'修饰符标记此方法,并将其返回类型更改为'task' 但是,如果我使用async修饰符,这将是一个异步操作。因此,如果我对的调用没有使用await运算符

  • 我可能还不够清楚--情况是,我的现有代码不支持异步,我希望使用新的库,如System.net.http和只支持异步方法的AWS SDK。因此,我需要弥补这一差距,并能够拥有可以同步调用的代码,然后可以在其他地方调用异步方法。 我读了很多书,有很多次有人问这个问题,也有人回答这个问题。 从非异步方法调用异步方法

  • 问题内容: 我使用的是Spring 4,我注意到了一个奇怪的行为……如果我从普通实例方法多次调用异步方法,那么它们都将在不同的线程中调用,并在随机时间完成。但是,如果我多次从另一个异步方法中调用一个异步方法,那么它们将按顺序完成。我有这样的事情: 我正在使用默认的异步执行器。我应该换一个吗?但是,该执行程序不会重用任何线程,而是每次都启动另一个线程,因此应该没问题……这仅仅是巧合吗?但是我尝试了十

  • 没有await并且在非异步方法中调用异步方法的行为是什么?我这样问是因为我看到Visual Studio在调用异步方法时没有显示任何警告,好像这是一件非常正常的事情。在这种情况下,异步方法的行为是否像是同步的?