0

I have a servlet that I want to serve data to a web UI. the data is stored in an xml file which I expect to be modified once in a couple of days. I want to load the xml file in the servlet once, and serve it for each request, and reload it only when I send another 'reload' request.

From what I've read, static variables in servlet is bad practice.

How can I achieve what I need?

thanks.

user1997656
  • 472
  • 1
  • 6
  • 15

6 Answers6

3

I've really come to dislike the term "bad practice", as it insinuates that we can assess whether something is bad irrespective of circumstances. Such is rarely the case - or put differently, if the designers of the Java language had thought static fields to be always bad, they wouldn't have included them in the language.

It's totally ok to have mutable state in a servlet - but you have to keep in mind the servlet container will use the same object instance of the servlet to (concurrently) serve all requests.

This implies that state specific to the request should not be stored in the servlet, because the different request processing threads would overwrite each other's state. In your case though, you want state to be shared across all requests, so a field in the servlet is appropriate. As the servlet is accessed by concurrent threads, you will however have to synchronize access to that mutable shared state.

meriton
  • 61,876
  • 13
  • 96
  • 163
  • How do I synchronize access to the data in a servlet? just wrap the method with synchronized? – user1997656 May 12 '13 at 11:15
  • How to write correct thread-safe code is beyond the scope of this answer. The java tutorials have an [introduction](http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html) to the topic. – meriton May 12 '13 at 11:22
2

A servlet is created only once on webapp's startup and shared among all requests. Static or not, every class/instance variable is going to be shared among all requests/sessions. You would not like to assign request/session scoped data to them. Rather declare/assign them as methodlocal variable

SEE HERE

Community
  • 1
  • 1
PSR
  • 36,137
  • 33
  • 104
  • 147
1

You can use Singleton pattern or CDI application scoped beans depends on your environment.

And do not forget about thread-safety.

public class ServletSingleton {
    private static ServletSingleton instance = new ServletSingleton();

    //Here is your data objects
    private Object firstDataObject;
    private Object secondDataObject;

    public static Object getFirstDataObject(){
        synchronized (instance){
            return instance.firstDataObject;
        }
    }

    public static Object getSecondDataObject(){
        synchronized (instance){
            return instance.secondDataObject;
        }
    }

    public static void setFirstDataObject(Object dataObject){
        synchronized (instance){
            instance.firstDataObject = dataObject;
        }
    }

    public static void setSecondDataObject(Object dataObject){
        synchronized (instance){
            instance.secondDataObject = dataObject;
        }
    }
}

This is not familiar singleton, but it uses the same principles.

gluckonavt
  • 216
  • 1
  • 4
1

You could put the data in ServletContext, it's the context per "web application" per Java Virtual Machine(means global).

Check the usage here: http://www.javatpoint.com/servletcontext

ltebean
  • 1,009
  • 6
  • 15
0

just create a static variable, you dont have to do anything more

Dima
  • 8,448
  • 4
  • 25
  • 56
0

You can define an instance members or store the attribute into the application scope but both of them are not thread safe.

user2269148
  • 147
  • 2
  • 9