Java Rest API在JAX-RS中调用另一个Rest而不等待响应

时间:2018-03-09 12:36:56

标签: java rest web-services jax-rs

我有一个案例要在我的项目中实施。下面是一个必须实施的样本休息服务

'0'

使用新线程调用第二个休息API并返回结果而不等待第二个休息API的响应这是一个好方法吗? 我也研究过Asynchronous Rest调用,但它并不完全符合我的要求。请指教。在此先感谢

3 个答案:

答案 0 :(得分:3)

避免直接启动Thread。请考虑使用ExecutorService,如下所示:

@Singleton
@Path("foo")
public class FooResource {

    private ExecutorService executor;

    @PostConstruct
    public void onCreate() {

        // Creates a thread pool that reuses a fixed number 
        // of threads operating off a shared unbounded queue
        this.executor = Executors.newFixedThreadPool​(10);
    }

    @GET
    public Response getFoo() {

        String result = doSomeProcessing();

        // Submits a Runnable task for execution
        executor.submit(new LongRunningTask());

        return Response.ok(result).build();
    }

    @PreDestroy
    public void onDestroy() {

        // Initiates an orderly shutdown in which previously submitted 
        // tasks are executed, but no new tasks will be accepted.
        this.executor.shutdownNow();
    }
}
public class LongRunningTask implements Runnable {

    @Override
    public void run() {

        try {
            // Simulate a long running task
            // Don't do it in a real application
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

浏览Executors API,了解有关如何创建ExecutorService实例的详细信息。

在Java SE和Servlet容器中,您可以使用ExecutorService来执行长时间运行的任务。在Java EE容器中,您应该使用ManagedExecutorService代替:

@Resource
ManagedExecutorService executor;

一旦它是由容器管理的资源,您就不需要手动实例化和处理它。

答案 1 :(得分:2)

我不确定你是什么意思"调用第二个REST API"所以我假设您正在向另一个外部API发送HTTP请求,即第二个REST API"。

您可以使用Apache HC发送请求并跳过等待响应。查看易于使用的fluent APIAsync.execute是你应该使用的那个。 Async类使用下面的线程池来处理后台请求。

我应该提一下,我还没有使用过任何其他HTTP客户端库。可能还有其他选择具有几乎相同的功能。

旁注我强烈建议ExecutorService,尤其是ThreadPoolExecutor而不是创建新线程。它可以更好地控制线程的生命周期,并有效地管理系统资源。 ExecutorService具有针对火灾和遗忘方案的方法(submit)。但是,这只适用于您的第二个REST API" call实际上是在应用程序中的另一个方法中实现的,并且位于同一个JRE中。

答案 2 :(得分:0)

我会说是,不是;关于异步调用另一个服务没有任何“错误”(例如:注册调用该服务的指标子系统)。但是,我不会在getData方法中直接创建线程,我会使用另一个(注入)对象来隐藏实现细节(例如:只是调用某种myOtherService.submit(something)。这样你就可以轻松从同步的东西切换到异步,甚至根据自己的喜好改变异步方法。

关于实际的实现,我不是创建线程,而是将callables提交给执行者服务,这样你就可以节省创建实际系统线程的开销,或者甚至可以让一个或多个线程在阻塞队列上等待将作业放在该队列中以供线程拾取它们。