title: Java JAX-RS web service: adding nodes to JAXB XML result as threads complete
body: <p>I have programmed a JAX-RS web service with Jersey that queries prices from different websites and gives the result back as XML through JAXB annotated classes. Unfortunately some websites take up to 15 seconds to respond so I am using multiple threads to inquire those prices. </p>
  
  <p>I would like to write a client to this webservice now and my web users will not want to wait for 30 seconds after they hit 'search' for the result to come so my idea is dynamically updating the result table as the results from my JAX-RS webservice come back.</p>
  
  <p>After 30 seconds my webservice should time out and close the <code>&lt;result&gt;</code>-Element or after all threads completed.</p>
  
  <p><strong>Right now my webservice runs all threads and gives back the result after all trheads are completed, I would like to dynamically add results to the XML output as they come, how can I accomplish that?</strong></p>
  
  <p>The structure of the XML response is:</p>
  
  <pre><code>&lt;result&gt;
    &lt;articles&gt;
      &lt;article&gt;
      content of article
      &lt;/article&gt;
    &lt;/articles&gt;
    As the webservice gets results from websites it adds new articles to the XML
  &lt;/result&gt;
  </code></pre>
  
  <hr>
  
  <h2>RequestController.java</h2>
  
  <pre><code>@Path("/request")
  public class RequestController {
  
      @GET
      @Produces("application/xml")
      public Response getRequest(@QueryParam("part") String part) {
          response = new Response();
          driverController = new DriverController(this.response, this.part);
          this.response = driverController.query();
          return this.response;
      }
  }
  </code></pre>
  
  <h2>DriverController.java</h2>
  
  <pre><code>public class DriverController {
  
  
      public Response query() {
          CompletionService&lt;Deque&lt;Article&gt;&gt; completionService = new ExecutorCompletionService&lt;Deque&lt;Article&gt;&gt;(
                  Worker.getThreadPool());
          final Deque&lt;Article&gt; articleQueue = new LinkedList&lt;Article&gt;();
  
          int submittedTasks = 0;
  
          // This threadwill take about 4 seconds to finish
          Driver driverA = new DriverA(this.part,
                  this.currency, this.language);
  
          // This thread will take about 15 seconds to finish
          Driver driverN = new DriverN(this.part,
                  this.currency, this.language);
  
          completionService.submit(driverA);
          submittedTasks++;
          completionService.submit(driverN);
          submittedTasks++;
  
          for (int i = 0; i &lt; submittedTasks; i++) {
              log.info("Tasks: " + submittedTasks);
              try {
                  Future&lt;Deque&lt;Article&gt;&gt; completedFuture = completionService.take();
                  try {
                      Deque&lt;Article&gt; articleQueueFromThread = completedFuture.get();
                      if (articleQueueFromThread != null) {
                          articleQueue.addAll(articleQueueFromThread);
                          response.setStatus("OK");
                      }
                  } catch (ExecutionException e) {
                      log.error(e.getMessage());
                      e.printStackTrace();
                  }
              } catch (InterruptedException e) {
                  log.error(e.getMessage());
                  e.printStackTrace();
              }
          }
          for (Article article : articleQueue) {
              this.response.addArticle(article);
          }
          return this.response;
      }
  }
  </code></pre>
  
  <h2>Response.java</h2>
  
  <pre><code>@XmlRootElement
  public class Response {
  
      Queue&lt;Article&gt; queue = new ConcurrentLinkedQueue&lt;Article&gt;();
      private String status;
      private String code;
      private String message;
      private List&lt;Article&gt; articles = new ArrayList&lt;Article&gt;();
  
      public Response(){
  
      }
  
      public void setMessage(String message) {
          this.message = message;
      }
      @XmlAttribute
      public String getMessage() {
          return message;
      }
      public void setStatus(String status) {
          this.status = status;
      }
      @XmlAttribute
      public String getStatus() {
          return status;
      }
      public void setCode(String code) {
          this.code = code;
      }
      @XmlAttribute
      public String getCode() {
          return code;
      }
  
      public void addArticle(Article article) {
          this.articles.add(article);
          System.out.println("Response: ADDED ARTICLE TO RESPONSE");
      }
      @XmlElement(name = "article")
      @XmlElementWrapper(name = "articles")
      public List&lt;Article&gt; getArticles() {
          return articles;
      }
  
  }
  </code></pre>