Java 如何向不同的web服务发送多个异步请求?

Java 如何向不同的web服务发送多个异步请求?,java,web-services,jakarta-ee,soap-client,rest-client,Java,Web Services,Jakarta Ee,Soap Client,Rest Client,我需要向许多不同的web服务发送多个请求并接收结果。问题是,如果我一个接一个地发送请求,那么我需要单独发送和处理所有请求 我想知道如何一次发送所有请求并接收结果 正如下面的代码所示,我有三个主要方法,每个方法都有自己的子方法。 每个子方法向其关联的web服务发送请求并接收结果;因此,例如,要接收web服务9的结果,我必须等到从1到8的所有web服务完成后,才能逐个发送所有请求并接收它们的结果,这需要很长时间 如下图所示,所有方法和子方法都互不相关,因此我可以调用它们并按任意顺序接收它们的结果,唯

我需要向许多不同的web服务发送多个请求并接收结果。问题是,如果我一个接一个地发送请求,那么我需要单独发送和处理所有请求

我想知道如何一次发送所有请求并接收结果

正如下面的代码所示,我有三个主要方法,每个方法都有自己的子方法。 每个子方法向其关联的web服务发送请求并接收结果;因此,例如,要接收web服务9的结果,我必须等到从1到8的所有web服务完成后,才能逐个发送所有请求并接收它们的结果,这需要很长时间

如下图所示,所有方法和子方法都互不相关,因此我可以调用它们并按任意顺序接收它们的结果,唯一重要的是接收每个子方法的结果并填充它们的关联列表

private List<StudentsResults> studentsResults = new ArrayList();
private List<DoctorsResults> doctorsResults = new ArrayList();
private List<PatientsResults> patientsResults = new ArrayList();

main (){
    retrieveAllLists();
}

retrieveAllLists(){

     retrieveStudents();
     retrieveDoctors();
     retrievePatients();
}

retrieveStudents(){

    this.studentsResults = retrieveStdWS1();   //send request to Web Service 1 to receive its  list of students
    this.studentsResults = retrieveStdWS2();  //send request to Web Service 2 to receive its  list of students
    this.studentsResults = retrieveStdWS3(); //send request to Web Service 3 to receive its  list of students

}

retrieveDoctors(){

   this.doctorsResults = retrieveDocWS4();   //send request to Web Service 4 to receive its list of doctors
   this.doctorsResults = retrieveDocWS5();  //send request to Web Service 5 to receive its  list of doctors
   this.doctorsResults = retrieveDocWS6(); //send request to Web Service 6 to receive its  list of doctors

}

retrievePatients(){

   this.patientsResults = retrievePtWS7();   //send request to Web Service 7 to receive its list of patients
   this.patientsResults = retrievePtWS8();  //send request to Web Service 8 to receive its list of patients
   this.patientsResults = retrievePtWS9(); //send request to Web Service 9 to receive its list of patients

}
private List studentsResults=new ArrayList();
private List doctorsResults=new ArrayList();
private List patientsResults=new ArrayList();
主要(){
retrieveAllList();
}
检索列表(){
检索学生();
检索器();
检索患者();
}
检索学生(){
this.studentsResults=retrieveStdWS1();//向Web服务1发送请求以接收其学生列表
this.studentsResults=retrieveStdWS2();//向Web服务2发送请求以接收其学生列表
this.studentsResults=retrieveStdWS3();//向Web服务3发送请求以接收其学生列表
}
检索器(){
this.doctorsResults=retrieveDocWS4();//向Web服务4发送请求以接收其医生列表
this.doctorsResults=retrieveDocWS5();//向Web服务5发送请求以接收其医生列表
this.doctorsResults=retrieveDocWS6();//向Web服务6发送请求以接收其医生列表
}
检索患者(){
this.patientsResults=retrievePtWS7();//向Web服务7发送请求以接收其患者列表
this.patientsResults=retrievePtWS8();//向Web服务8发送请求以接收其患者列表
this.patientsResults=retrievePtWS9();//向Web服务9发送请求以接收其患者列表
}

它有多种选择来开发此功能

  • JMS:服务质量和管理,例如重新交付尝试、死消息队列、负载管理、可伸缩性、集群、监控等
  • 只需为此使用观察者模式。有关更多详细信息以及如何解决产品和消费者问题,请参见**

  • 这是一种简单的fork-join方法,但为了清楚起见,您可以启动任意数量的线程,并在稍后检索可用的结果,例如这种方法

        ExecutorService pool = Executors.newFixedThreadPool(10);
        List<Callable<String>> tasks = new ArrayList<>();
        tasks.add(new Callable<String>() {
            public String call() throws Exception {
                Thread.sleep((new Random().nextInt(5000)) + 500);
                return "Hello world";
            }
    
        });
        List<Future<String>> results = pool.invokeAll(tasks);
    
        for (Future<String> future : results) {
            System.out.println(future.get());
        }
        pool.shutdown();
    
    ExecutorService池=Executors.newFixedThreadPool(10);
    列表任务=新建ArrayList();
    tasks.add(newcallable()){
    公共字符串调用()引发异常{
    Thread.sleep((new Random().nextInt(5000))+500);
    返回“你好世界”;
    }
    });
    列表结果=pool.invokeAll(任务);
    用于(未来:结果){
    System.out.println(future.get());
    }
    pool.shutdown();
    
    更新、完成:

    这里有一个冗长但可行的解决方案。我是临时写的,还没有编译。 鉴于这三个列表具有不同的类型,并且WS方法是单独的,所以它不是 真正的模块化,但是试着使用你最好的编程技巧,看看你是否能更好地模块化它

        ExecutorService pool = Executors.newFixedThreadPool(10);
    
        List<Callable<List<StudentsResults>>> stasks = new ArrayList<>();
        List<Callable<List<DoctorsResults>>> dtasks = new ArrayList<>();
        List<Callable<List<PatientsResults>>> ptasks = new ArrayList<>();
    
        stasks.add(new Callable<List<StudentsResults>>() {
            public List<StudentsResults> call() throws Exception {
                return retrieveStdWS1();
            }
    
        });
        stasks.add(new Callable<List<StudentsResults>>() {
            public List<StudentsResults> call() throws Exception {
                return retrieveStdWS2();
            }
    
        });
        stasks.add(new Callable<List<StudentsResults>>() {
            public List<StudentsResults> call() throws Exception {
                return retrieveStdWS3();
            }
    
        });
    
        dtasks.add(new Callable<List<DoctorsResults>>() {
            public List<DoctorsResults> call() throws Exception {
                return retrieveDocWS4();
            }
    
        });
        dtasks.add(new Callable<List<DoctorsResults>>() {
            public List<DoctorsResults> call() throws Exception {
                return retrieveDocWS5();
            }
    
        });
        dtasks.add(new Callable<List<DoctorsResults>>() {
            public List<DoctorsResults> call() throws Exception {
                return retrieveDocWS6();
            }
    
        });
    
        ptasks.add(new Callable<List<PatientsResults>>() {
            public List<PatientsResults> call() throws Exception {
                return retrievePtWS7();
            }
    
        });
        ptasks.add(new Callable<List<PatientsResults>>() {
            public List<PatientsResults> call() throws Exception {
                return retrievePtWS8();
            }
    
        });
        ptasks.add(new Callable<List<PatientsResults>>() {
            public List<PatientsResults> call() throws Exception {
                return retrievePtWS9();
            }
    
        });
    
        List<Future<List<StudentsResults>>> sresults = pool.invokeAll(stasks);
        List<Future<List<DoctorsResults>>> dresults = pool.invokeAll(dtasks);
        List<Future<List<PatientsResults>>> presults = pool.invokeAll(ptasks);
    
        for (Future<List<StudentsResults>> future : sresults) {
           this.studentsResults.addAll(future.get());
        }
        for (Future<List<DoctorsResults>> future : dresults) {
           this.doctorsResults.addAll(future.get());
        }
        for (Future<List<PatientsResults>> future : presults) {
           this.patientsResults.addAll(future.get());
        }
        pool.shutdown();
    
    ExecutorService池=Executors.newFixedThreadPool(10);
    List statsks=new ArrayList();
    List dtasks=new ArrayList();
    List ptasks=new ArrayList();
    stasks.add(新的可调用(){
    公共列表调用()引发异常{
    返回retrieveStdWS1();
    }
    });
    stasks.add(新的可调用(){
    公共列表调用()引发异常{
    返回retrieveStdWS2();
    }
    });
    stasks.add(新的可调用(){
    公共列表调用()引发异常{
    返回retrieveStdWS3();
    }
    });
    添加(新的可调用(){
    公共列表调用()引发异常{
    返回retrieveDocWS4();
    }
    });
    添加(新的可调用(){
    公共列表调用()引发异常{
    返回retrieveDocWS5();
    }
    });
    添加(新的可调用(){
    公共列表调用()引发异常{
    返回retrieveDocWS6();
    }
    });
    ptasks.add(新的可调用(){
    公共列表调用()引发异常{
    返回retrievePtWS7();
    }
    });
    ptasks.add(新的可调用(){
    公共列表调用()引发异常{
    返回retrievePtWS8();
    }
    });
    ptasks.add(新的可调用(){
    公共列表调用()引发异常{
    返回retrievePtWS9();
    }
    });
    List sresults=pool.invokeAll(stasks);
    List-dresults=pool.invokeAll(dtasks);
    List presults=pool.invokeAll(ptasks);
    for(未来:sresults){
    this.studentsResults.addAll(future.get());
    }
    for(未来:dresults){
    this.doctorsResults.addAll(future.get());
    }
    for(未来:预设){
    this.patientsResults.addAll(future.get());
    }
    pool.shutdown();
    
    每个
    Callable
    返回一个结果列表,并在其各自的单独线程中调用。
    调用
    Future.get()
    方法时,会将结果返回到主线程。

    可调用的
    完成之前,结果不可用,因此不存在并发问题。

    看看这个问题,您需要将应用程序与10多个不同的Web服务集成。同时使所有调用异步。这可以通过ApacheCamel轻松完成。它是一个突出的企业整合框架
    import java.util.ArrayList;
    
    public class ThreadingExample
    {
        private ArrayList <MyThread> myThreads;
    
        public static class MyRunnable implements Runnable
        {
            private String data;
    
            public String getData()
            {
                return data;
            }
    
            public void setData(String data)
            {
                this.data = data;
            }
    
            @Override
            public void run()
            {
            }
        }
    
        public static class MyThread extends Thread
        {
            private MyRunnable myRunnable;
    
            MyThread(MyRunnable runnable)
            {
                super(runnable);
                setMyRunnable(runnable);
            }
    
            /**
             * @return the myRunnable
             */
            public MyRunnable getMyRunnable()
            {
                return myRunnable;
            }
    
            /**
             * @param myRunnable the myRunnable to set
             */
            public void setMyRunnable(MyRunnable myRunnable)
            {
                this.myRunnable = myRunnable;
            }
        }
    
        public ThreadingExample()
        {
            myThreads = new ArrayList <MyThread> ();
        }
    
        public ArrayList <String> retrieveMyData ()
        {
            ArrayList <String> allmyData = new ArrayList <String> ();
    
            if (isComplete() == false)
            {
                // Sadly we aren't done
                return (null);
            }
    
            for (MyThread myThread : myThreads)
            {
                allmyData.add(myThread.getMyRunnable().getData());
            }
    
            return (allmyData);
        }
    
        private boolean isComplete()
        {
            boolean complete = true;
    
            // wait for all of them to finish
            for (MyThread x : myThreads)
            {
                if (x.isAlive())
                {
                    complete = false;
                    break;
                }
            }
            return (complete);
        }
    
        public void kickOffQueries()
        {
            myThreads.clear();
    
            MyThread a = new MyThread(new MyRunnable()
            {
                @Override
                public void run()
                {
                    // This is where you make the call to external services
                    // giving the results to setData("");
                    setData("Data from list A");
                }
            });
            myThreads.add(a);
    
            MyThread b = new MyThread (new MyRunnable()
            {
                @Override
                public void run()
                {
                    // This is where you make the call to external services
                    // giving the results to setData("");
                    setData("Data from list B");
                }
            });
            myThreads.add(b);
    
            for (MyThread x : myThreads)
            {
                x.start();
            }
    
            boolean done = false;
    
            while (done == false)
            {
                if (isComplete())
                {
                    done = true;
                }
                else
                {
                    // Sleep for 10 milliseconds
                    try
                    {
                        Thread.sleep(10);
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    
        public static void main(String [] args)
        {
            ThreadingExample example = new ThreadingExample();
            example.kickOffQueries();
    
            ArrayList <String> data = example.retrieveMyData();
            if (data != null)
            {
                for (String s : data)
                {
                    System.out.println (s);
                }
            }
        }
    }
    
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class ThreadingExample
    {
    
        public static void main(String [] args)
        {
            ExecutorService service = Executors.newCachedThreadPool();
            Set <Callable<String>> callables = new HashSet <Callable<String>> ();
    
            callables.add(new Callable<String>()
            {
                @Override
                public String call() throws Exception
                {
                    return "This is where I make the call to web service A, and put its results here";
                }
            });
    
            callables.add(new Callable<String>()
            {
                @Override
                public String call() throws Exception
                {
                    return "This is where I make the call to web service B, and put its results here";
                }
            });
    
            callables.add(new Callable<String>()
            {
                @Override
                public String call() throws Exception
                {
                    return "This is where I make the call to web service C, and put its results here";
                }
            });
    
            try
            {
                List<Future<String>> futures = service.invokeAll(callables);
                for (Future<String> future : futures)
                {
                    System.out.println (future.get());
                }
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            catch (ExecutionException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    <bindings ...>    
        <bindings node="wsdl:definitions">
            <enableAsyncMapping>true</enableAsyncMapping>
        </bindings>    
    </bindings>
    
    public void retrieveAllLists() throws ExecutionException{
        // first fire all requests
        Response<List<StudentsResults>> students1 = ws1.getStudents();
        Response<List<StudentsResults>> students2 = ws2.getStudents();
        Response<List<StudentsResults>> students3 = ws3.getStudents();
    
        Response<List<DoctorsResults>> doctors1 = ws4.getDoctors();
        Response<List<DoctorsResults>> doctors2 = ws5.getDoctors();
        Response<List<DoctorsResults>> doctors3 = ws6.getDoctors();
    
        Response<List<PatientsResults>> patients1 = ws7.getPatients();
        Response<List<PatientsResults>> patients2 = ws8.getPatients();
        Response<List<PatientsResults>> patients3 = ws9.getPatients();
    
        // then await and collect all the responses
        studentsResults.addAll(students1.get());
        studentsResults.addAll(students2.get());
        studentsResults.addAll(students3.get());
    
        doctorsResults.addAll(doctors1.get());
        doctorsResults.addAll(doctors2.get());
        doctorsResults.addAll(doctors3.get());
    
        patientsResults.addAll(patients1.get());
        patientsResults.addAll(patients2.get());
        patientsResults.addAll(patients3.get());
    }
    
    private class StudentsCallbackHandler 
                implements AsyncHandler<Response<List<StudentsResults>>> {
        public void handleResponse(List<StudentsResults> response) {
            try {
                studentsResults.addAll(response.get());
            } catch (ExecutionException e) {
                errors.add(new CustomError("Failed to retrieve Students.", e.getCause()));
            } catch (InterruptedException e) {
                log.error("Interrupted", e);
            }
        }
    }
    
    public void retrieveAllLists() {
        List<Future<?>> responses = new ArrayList<Future<?>>();
        // fire all requests, specifying callback handlers
        responses.add(ws1.getStudents(new StudentsCallbackHandler()));
        responses.add(ws2.getStudents(new StudentsCallbackHandler()));
        responses.add(ws3.getStudents(new StudentsCallbackHandler()));
    
        ...
    
        // await completion 
        for( Future<?> response: responses ) {
            response.get();
        }
    
        // or do some other work, and poll response.isDone()
    }