I have a self-made framework/API and it does some database searches that can take a long time. A long time means several seconds up to minutes depending on input. The search puts found results into a java.util.concurrent.BlockingQueue. Hence the first search result is immediatley available.
I would now like to create a search page and after submitting the search the results page instantly loads with these first hits and then periodically adds subsequent hits until the search completed. How could I do that?
OK. I came up with a solution.
BIG WARNING:
untested for production use!
Used javascript dependencies: JQuery, jquery datatables plug-in (http://datatables.net) and fnStandingRedraw plugin for datatables.
Java Dependencies: googles Gson library
I have a search page that submits to a servlet.
The servlet starts the search and puts the search thread and the BlockingQueue into session and then redirects to the results page:
Note that the Queue is filled with the primary key from the database, hence integer.
The results page needs following references:
and following javascript code to initialize the table and add rows:
Please also refer to the datatables homepage on how to setup such a table.
The JQuery get-function is called periodically based on a timer. It calls another servlet that reads from the Queue and returns new hits formated as JSON:
The limit and timers might need to be adjusted depending on your purpose. The limit is there so that new results are actually added periodically. (If getting the data is slower than the rate at which new hits are found, then nothing would be returned and displayed until search finishes).
Note that the string myData can be HTML and it is rendered as HTML. In my case I return image tags. And those image tags have another servlet as source that creates the images dynamically. Note that the datatables option “bDeferRender”: true only renders the according rows (and in my case images) once they get visible for the first time. Eg. if a user only looks at the first 3 pages, pages 4-100 never actually get rendered. And if a user clicks on the last page only the last one gets rendered not all in between.
Please comment in case of questions or improvements / possible bugs.