如何使用executorService在J2EE应用程序中进行http调用

时间:2018-04-18 09:40:31

标签: java java-ee executorservice

我想知道在无状态bean中使用ManagedExecutorService。基本上我试图在我的j2EE应用程序内的一个单独的线程中发送一个http调用。 executorService发送此请求并等待x秒以接收响应,如果在指定的秒内没有响应或者获取exeception然后再尝试(X次),然后最终给出https服务调用成功完成或失败的反馈。这是我的代码

@SuppressWarnings("EjbEnvironmentInspection")
@Resource
ManagedExecutorService executorService;

public static final long RETRY_DELAY = 3000;
public static final int MAX_RETRIES = 3;
 executorService.execute(() -> {
        int retry = 0;
        Collection<Info> responseInfo = null;

        while (responseInfo == null && retry++ < MAX_RETRIES) {
            try {
                responseInfo = httpsService.requestAccessInfo(requestInfo);
                Thread.sleep(RETRY_DELAY);
            } catch (Exception e) {
                log.error("Error while receiving response retry attempt {}", retry);
            }
        }

        boolean status = filledLockAccessInfo==null ? false : true;

        event.fire(regularMessage(status,GENERATION_RESULT);

    });

有人可以告诉我这是否是正确的方法。

1 个答案:

答案 0 :(得分:1)

你不应该强行睡觉(Thread.sleep(RETRY_DELAY);)。您需要的是异步调用可支持超时的服务。

以下两种方法使用可完成的未来API超时和错误处理来实现它。

以下使用递归来重试给定次数:

private static Collection<Info> callService(int retryCount) {

    try {
        CompletableFuture<Collection<Info>> f =  invoke();
        return f.get(RETRY_DELAY, TimeUnit.MILLISECONDS);
    }catch(TimeoutException te) {
        if(retryCount > 0) {
            return callService(retryCount - 1);
        } else {
            throw new RuntimeException("Fatally failed!!");
        }
    } catch(Exception ee) {
        throw new RuntimeException("Unexpectedly failed", ee);
    }
}

请注意,executorService对象在supplyAsync

的第二个参数中传递
private static CompletableFuture<Collection<Info>> invoke() {
    return CompletableFuture.supplyAsync(() -> {
        //call
        return httpsService.requestAccessInfo(requestInfo);;
    }, executorService);
}

有了这个,你可以简单地用重试次数来调​​用它:

Collection<Info> responseInfo = callService(MAX_RETRIES);

要使上述调用异步运行,可以将前面的语句替换为:

CompletableFuture.supplyAsync(() -> callService(MAX_RETRIES))
            .thenAccept(res -> System.out.println("Result: " + res));

这将在后台进行通话。稍后,您可以查看它是如何完成的:

f.isCompletedExceptionally() //will tell whether it completed with an exception.