Link to home
Start Free TrialLog in
Avatar of angelzworld
angelzworld

asked on

Share client data between servlets

I have to display a recordset on the same web page as a graph as well as an HTML table. I am using JFreeChart for the graph. The problem I am facing is how do I display both the graph(image) and the HTML table on the same web page using a single servlet. The response type for the image is "image/png" and for the table is "text/html". I am displaying the image by calling a particular servlet from the "src" attribute of an <img> tag which returns the generated image using the responses outputstream. I am not sure if I can use the same servlet to return the HTML table as well..

The main concern is the query shouldnt be run twice , i.e database calls shouldnt happen again as the resultset for both the image and the table is the same..So even if I use different servlets to display the image and the table , I need to share the  data structure(a vector in this case which stores the results of the query) in both the servlets.

How do I share data between two different servlets, which would be different per client session. I am thinking of using RequestDispatcher to store the data structure in the Context , however not sure if this is a good approach or not.

Also my application uses opensymphony Action Classes for server side programming.

Experts awaiting your suggestions. Some sample code or links to some sample code would be highly appreciated.

Avatar of mukundha_expert
mukundha_expert

>>How do I share data between two different servlets

create a HttpSession and set the attribute of the sesssion to hold your values,


like,

session = request.getSession () ;
session.setAttribute ( "MyData" , MyObjobject ) ;
this session can be accessed by the different servlets belonging to the same application.

after setting the session attribute, forward the request to other servlet

Avatar of Mayank S
>> RequestDispatcher to store the data structure in the Context

You mean in the servlet context? How would you use Request-dispatcher to do that? Per client session data should be stored in the predefined session object like shown by mukundha. Request-dispatcher is more for dispatching requests/ responses. You can store the objects in the request and forward to another page if the data pertains to only that request, but if the data needs to be available for further use in the same session, you should use session.
      Hi!

Use QueryString parameters ( like domain.com?action=pict or action=table)
 and have 2 different private functions which outputs either the picture or the table.
Put the ResultSet in a static HashMap with the SessionID as key to retrieve the result in later requests.

Regards,
  Tomas Helgi
Puting large resultsets in Sessions results in poor performance on the webserver.
 
Regards,
  Tomas Helgi
Avatar of angelzworld

ASKER

The resultset would change for the same client, hence doesnt need to persist over different requests. The client selects a particular time range for which the graph and the table needs to be displayed. The start time and the end time are passed as parameters to the servlet and depending on that , records are retrieved from the database. Now using this resutlset , I generate a graph as well as an HTML table which displays only the last 20 records of the resutlset.

My problem is I dont know how to display both the graph and the table on the same page with only one call to the database. I was using the following code to dsiplay the image.

/*************************************************/
OutputStream out = response.getOutputStream();
response.setContentType("image/png");
ChartUtilities.writeChartAsPNG(out, chart, 500, 400); //chart is the generated JFreeChart object
/**************************************************/

On the client side , the servlet is called as follows:(parameter values set using apache velocity)

/**************************************************/
 <img src="chartGenerator?serialNumber=$serialNumber&FromTime=$FromTime&ToTime=$ToTime" width="500" height="400">
/**************************************************/

I dont think I should be making two separate calls to the same servlet to generate a graph and a table. Once I set the response type to image , I am not sure how do I go about displaying the table on the same page.  I am sure there is a much better and easier way to do this , than to store the session id and all..I hope I am clearer about what I want to do this time.
>> hence doesnt need to persist over different requests

I thought you had to persist it: >> hence doesnt need to persist over different requests

But if not, then you don't need it in the session.

>> My problem is I dont know how to display both the graph and the table on the same page with only one call to the database

Try putting both in a frame/ iFrame. Otherwise, instead of writing the image using response.setContentType (), etc you can just give a link to it in the other page using <img src = "imagefilepath.png" width height etc />
    HI!

In a doGet or doPost method retrieve the Parameter (in my example action) and if action=pict call function outputpicture and if action=table call the function outputtable.  Let each private function set the response type to either image/png or text/html.
Then let the first private function set the Resultset into the static hashmap with SessionID as key.
Then when you call the web-page that includes urls to the servlets you only call the db once per webpage refresh.
But several servlets can process the ResultSet in the same request.

Regards,
  Tomas Helgi  
>> you can just give a link to it in the other page using <img src = "imagefilepath.png" width height etc />

didnt quite get this..if i m using <img src = "imagefilepath.png" >...then i have a png file which represents the graph..however I dont have a file generated as the image is written to the output stream and not saved , each time its generated for every different request.

I am fine with using different servlets to generate the graph and table separately , but the query shuldnt be run in both the servlets as I said earlier. Needs to be run only once and results retrieved are used by both the servlets to generate the graph and the table.If this approavh is used, the question that arises is how do i share the resultset between those servlets for a particular request. The resultset changes for every request.
give a link to the image like this
<img src="/pathtoservlet/servlet?action=picture...">......

Regards,
  Tomas Helgi
The first servlet in the calling order should call the db and store the data in the Hashmap.
If the graph is above the table then the graphoutput-function should call the db and the other servlet just retrieves the ResultSet from the Hashmap.

Regards,
  Tomas Helg
Hie Tomas Helgi  

I had thought about the solution you suggested , however for this approach , wont the same servlet be called twice(once to generate the image and next to generate the table) for a single request?? I dont know if thats the right approach or not..

when a client submits the time range and hits the submit button , both the image and the table needs to be generated when the page reloads. I can call one servlet when i hit the submit button which generates the table and sets the resultset in memory somehow. Then call another servlet (via servlet chaining) to generate the image which uses the same resultset. Call this servlet using the image tag src attribute or call it thorugh the earlier one..But then again not sure how to share the resultset for two different servlets for the same request
>> Then let the first private function set the Resultset into the static hashmap with SessionID as key.
    Then when you call the web-page that includes urls to the servlets you only call the db once per webpage refresh.
    But several servlets can process the ResultSet in the same request.

>> If the graph is above the table then the graphoutput-function should call the db and the other servlet just retrieves the ResultSet from the Hashmap.

I am not clear on how does the first servlet set the Resultset into the static hashmap with SessionID as key and how the other servlet retrieves this stored resultset
Simple

here is an example on how to put value and get value from a Hashmap

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

class Counter {
  int i = 1;

  public String toString() {
    return Integer.toString(i);
  }
}

public class Statistics {
  private static Random rand = new Random();

  public static void main(String[] args) {
    Map hm = new HashMap();
    for (int i = 0; i < 10000; i++) {
      // Produce a number between 0 and 20:
      Integer r = new Integer(rand.nextInt(20));
      if (hm.containsKey(r))
        ((Counter) hm.get(r)).i++;
      else
        hm.put(r, new Counter());
    }
    System.out.println(hm);
  }
} ///:~

Regards,
   Tomas Helgi
No , I think you got me wrong. I know how to store and retrieve values from a hashmap. I am unclear on how to share  the hashmap structure between the two servlets.
still waiting for an answer..

again the constraints are..

for every request of time duration sent by client (same client can send multiple requests from same browser)

1. display table and image on SAME PAGE
2. use the SAME RECORDSET/DATA STRUCTURE  to generate both

doesnt matter if you use multiple servlets or a single servlet.


also i think the resultset would change for a particular session as well..as a session i think is associated for a particular client, whereas the resultset would be generated for every request that the client makes
ASKER CERTIFIED SOLUTION
Avatar of Tomas Helgi Johannsson
Tomas Helgi Johannsson
Flag of Iceland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Its a lot easier to just save the image's bytes in a file (in the same servlet which generates it) and then provide a link to the file using <img> tag.

hey mayankeagle
If I get your right , you are suggesting that I save the image in a file on the filesystem on the server?I dont want to do that as I would have to save one file per cleint request. Please correct me if I am wrong.

I am goin to try your approach tomas and c if it works out.
Correct, you can delete the files after some time if you want using File.delete ()
I finally ended up using a complete different query to retrieve the results from the database, but limiting the recordset to 20 records. This seems to be the fastest approach. However I did implement your solution Tomas and would have chosen it , but want to keep things simple. Thanks for all your help experts. :)