Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6215305
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T07:01:56+00:00 2026-05-24T07:01:56+00:00

I have programmed a JAX-RS web service with Jersey that queries prices from different

  • 0

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.

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.

After 30 seconds my webservice should time out and close the <result>-Element or after all threads completed.

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?

The structure of the XML response is:

<result>
  <articles>
    <article>
    content of article
    </article>
  </articles>
  As the webservice gets results from websites it adds new articles to the XML
</result>

RequestController.java

@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;
    }
}

DriverController.java

public class DriverController {


    public Response query() {
        CompletionService<Deque<Article>> completionService = new ExecutorCompletionService<Deque<Article>>(
                Worker.getThreadPool());
        final Deque<Article> articleQueue = new LinkedList<Article>();

        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 < submittedTasks; i++) {
            log.info("Tasks: " + submittedTasks);
            try {
                Future<Deque<Article>> completedFuture = completionService.take();
                try {
                    Deque<Article> 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;
    }
}

Response.java

@XmlRootElement
public class Response {

    Queue<Article> queue = new ConcurrentLinkedQueue<Article>();
    private String status;
    private String code;
    private String message;
    private List<Article> articles = new ArrayList<Article>();

    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<Article> getArticles() {
        return articles;
    }

}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T07:01:56+00:00Added an answer on May 24, 2026 at 7:01 am

    I started to adapt your code to do it, but I decided it was easier to work up an independent example. The example starts a Grizzly+Jersey server with a single resource class in it. A GET on the resource spawns three threads that delay for 2, 4, and 6 seconds before returning some objects. After the server starts, another thread makes a request to the server. When you run it, you can plainly see that the requester receives chunks of XML as the respective threads finish their work in the server. The one thing it doesn’t do is wrap separately-delivered XML chunks in a single root element since that should be relatively trivial.

    The entire executable source is below, and if you have maven and git, you can clone it from github and run it with:

    git clone git://github.com/zzantozz/testbed.git tmp
    cd tmp
    mvn compile exec:java -Dexec.mainClass=rds.jersey.JaxRsResource -pl jersey-with-streaming-xml-response
    

    Source:

    import com.sun.grizzly.http.SelectorThread;
    import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
    import javax.ws.rs.*;
    import javax.ws.rs.core.StreamingOutput;
    import javax.xml.bind.*;
    import javax.xml.bind.annotation.*;
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import java.util.concurrent.*;
    
    @Path("/streaming")
    public class JaxRsResource {
        private static ExecutorService executorService = Executors.newFixedThreadPool(4);
        private static int fooCounter;
        private Marshaller marshaller;
    
        public JaxRsResource() throws JAXBException {
            marshaller = JAXBContext.newInstance(Foo.class).createMarshaller();
            marshaller.setProperty("jaxb.fragment", Boolean.TRUE);
        }
    
        @GET
        @Produces("application/xml")
        public StreamingOutput streamStuff() {
            System.out.println("Got request for streaming resource; starting delayed response threads");
            final List<Future<List<Foo>>> futureFoos = new ArrayList<Future<List<Foo>>>();
            futureFoos.add(executorService.submit(new DelayedFoos(2)));
            futureFoos.add(executorService.submit(new DelayedFoos(4)));
            futureFoos.add(executorService.submit(new DelayedFoos(6)));
            return new StreamingOutput() {
                public void write(OutputStream output) throws IOException {
                    for (Future<List<Foo>> futureFoo : futureFoos) {
                        writePartialOutput(futureFoo, output);
                        output.write("\n".getBytes());
                        output.flush();
                    }
                }
            };
        }
    
        private void writePartialOutput(Future<List<Foo>> futureFoo, OutputStream output) {
            try {
                List<Foo> foos = futureFoo.get();
                System.out.println("Server sending a chunk of XML");
                for (Foo foo : foos) {
                    marshaller.marshal(foo, output);
                }
            } catch (JAXBException e) {
                throw new IllegalStateException("JAXB couldn't marshal. Handle it.", e);
            } catch (InterruptedException e) {
                throw new IllegalStateException("Task was interrupted. Handle it.", e);
            } catch (ExecutionException e) {
                throw new IllegalStateException("Task failed to execute. Handle it.", e);
            }
        }
    
        class DelayedFoos implements Callable<List<Foo>> {
            private int delaySeconds;
    
            public DelayedFoos(int delaySeconds) {
                this.delaySeconds = delaySeconds;
            }
    
            public List<Foo> call() throws Exception {
                Thread.sleep(delaySeconds * 1000);
                return Arrays.asList(new Foo(fooCounter++), new Foo(fooCounter++), new Foo(fooCounter++));
            }
        }
    
        public static void main(String[] args) throws IOException {
            System.out.println("Starting Grizzly with the JAX-RS resource");
            final String baseUri = "http://localhost:9998/";
            final Map<String, String> initParams = new HashMap<String, String>();
            initParams.put("com.sun.jersey.config.property.packages", "rds.jersey");
            SelectorThread threadSelector = GrizzlyWebContainerFactory.create(baseUri, initParams);
            System.out.println("Grizzly started");
            System.out.println("Starting a thread to request the streamed XML");
            executorService.submit(new HttpRequester(baseUri + "streaming"));
        }
    }
    
    @XmlRootElement
    class Foo {
        @XmlElement
        private int id;
    
        Foo() {}
    
        public Foo(int id) {
            this.id = id;
        }
    }
    
    class HttpRequester implements Runnable {
        private String url;
    
        public HttpRequester(String url) {
            this.url = url;
        }
    
        public void run() {
            try {
                System.out.println("Doing HTTP GET on " + url);
                HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
                BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    System.out.println("Client got: " + line);
                }
                System.exit(0);
            } catch (IOException e) {
                throw new IllegalStateException("Some bad I/O happened. Handle it.", e);
            }
        }
    }
    

    Important points/differences to take note of:

    1. Returning a Response from your resource method indicates that the entire response is contained in that object and doesn’t allow for incremental updates to the response. Return a StreamingOutput instead. That tells Jersey that you’ll be sending back a stream of data, which you can append to at will until you’re done. The StreamingOutput gives you access to an OutputStream, which is what you use to send incremental updates and is the key to this whole thing. Of course, that means you have to handle the marshaling yourself. Jersey can only do the marshaling if you’re returning the entire response at once.
    2. Since the OutputStream is how you send back the data a little at a time, you either have to do the threading in your JAX-RS resource or pass the OutputStream down to your DriverController and write to it there.
    3. Be sure to invoke flush() on the OutputStream if you want to force it to send out data immediately. Otherwise, nothing will be sent to the client until whatever internal buffer is filled up. Note that invoking flush() yourself circumvents the purpose of the buffer and makes your app more chatty.

    All in all, to apply this to your project, the primary thing to do is change your resource method to return a StreamingOutput implementation and invoke your DriverController from inside that implementation, passing the OutputStream to the DriverController. Then in the DriverController, when you get some Articles back from a thread, instead of adding it to a queue for later, write it to the OutputStream immediately.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have never programmed web sites. I know that I can create web sites
I have programmed a sub procedure that will be called in the main procedure
I have a customer mangement system that I have programmed in php and mysql.
I'm an experienced Java programmer that for the last two years have programmed for
then, elif, else statement that I have programmed in a bash script. I know
I have programmed a bit of C++ back about 14 years ago. I got
I have programmed a simple app that every X minutes checks if an image
I have programmed a Windows Service in C# which should connect to an SQL-Server
I have programmed a plugin in Lua for a game that sends player information
I have programmed an emulator, but I have some doubts about how to organizate

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.