views:

284

answers:

5

I have a servlet which handles http get requests that I'd like to be able to share an object which is also used by a webservice im developing. They are both on the same tomcat server within the same web-app container. Im not sure best how to do it any ideas ?

+3  A: 

You can share things across the webapp by storing them as attributes in the ServletContext (using setAttribute / getAttribute). You could create the object in an impelementation of ServletContextListener, store it in the ServletContext, and then retrieve it and use it from your web service and servlet.

skaffman
but have in mind this is not safe if multiple users connect to your servlet. It can lead to unexpected results.
Bozho
Why do you say that?
skaffman
In any case you need to write this object in a thread safe manner.
David Rabinowitz
Much better approach than using **Singleton**. BTW, singleton also has to be thread safe.
Alexander Pogrebnyak
A shared object is a shared object, the thread safety is not relevant to *how* it is shared, which is the question.
skaffman
I said it, because I understood the question as if he wants to get an input from the user and then use this precise input to be sent via his web service (hence my comment on the question). That, of course, if a whole different scenario.
Bozho
Alexander let me make sure I understand you correctly you recommend the approach underlined by @skaffman ie using the setAttribute /getAttribute approach ?
wmitchell
@imerez. I've expanded my reply to an answer: http://stackoverflow.com/questions/1832691/sharing-a-static-object-between-a-servlet-and-a-webservice/1833526#1833526
Alexander Pogrebnyak
+1  A: 

The simplest option is create a Singleton - a class which allows only one instance in memory. Since you get it by calling a static method on the class itself it should be available to both the servlet and the WS

David Rabinowitz
Only if the servlet and the web service are in the same classloader...
Nate
My assumption from the question is that both located in the same webapp, and then there is no problem. However, your comment is correct.
David Rabinowitz
+1  A: 

I will expand on my comment here.

In the simplest case ServletContext.setAttribute/getAttribute would be fine. But some people rightly raised the questions about thread safety.

For this a better approach would be to store a shared POJO in a ServletContext during webapp initialization and get it wherever you need with ServletContext.getAttribute.

For this you need to implement ServletContextListener interface and declare it in your web.xml file.

<listener>
  <listener-class>your.package.ServletContextListenerImpl</listener-class>
</listener>

This listener is called once when your webapp is loaded by the servlet container, and when it is about to be unloaded by the servlet container. In both cases it passes ServletContextEvent that has a handle to ServletContext. It is at that point that you want to set/removeAttribute that points to your shared object.

Because of this you may be certain that ServletContext.getAttribute will return a valid object when called from the Servlet.service or one of the do... methods.

As for attribute name, I would go with your Shared class classname. I would also add a static access method to your shared class to get it from the ServletContext, like this:

public class Shared
{
  ...
  public static Shared fromServletContext ( final ServletContext context )
  {
    return (Shared) context.getAttribute( Shared.class.getName( ) );
  }
}
Alexander Pogrebnyak
A: 

If my alternative understanding of the question is correct, the data which comes from request should be stored, and then retreived by the web-service. If this is supposed to run in a multi-user environment, you might consider using an in-memory database (HSQLDB) to temporarily store the data. Then you will be able to retrieve it with your web-service, based on some criteria I cannot foretell.

Bozho
A: 

If this is application-specific data (accessible by all users (sessions)), then use ServletContext#set/getAttribute(). If this is user (session)-specific data, then use HttpSession#set/getAttribute().

Let the servlet class set the object in the desired scope (application or session) by a specific attribute key and let the webservice get the object from the desired scope by the same attribute key.

I think you rather need the HttpSession.

The singleton story makes no sense here.

BalusC
I have a feeling that the web service is called by a different machine/browser, thus generating a different session. But the case here is very obscure.
Bozho