Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreadLocal to store ServletRequest and Response in servlet: what for?

Once I have came across a pattern, where ServletRequest and response objects are put to servlet's local ThreadLocal variables. The servlet class has also methods to get current request and response objects. So in order to get these objects you still need to operate with servlet object.

What is the point of having these ThrealLocal local variables?

like image 275
glaz666 Avatar asked Mar 29 '11 13:03

glaz666


1 Answers

Since the request and the response objects are stored in thread local variables, you get thread safe access to those objects without having to pass them around as method parameters.

Example 1: Without thread local

public class MyServlet extends Servlet {
    private MyObject myObject = new MyObject();

    public void service(ServletRequest request, ServletResponse response) {
        myObject.doSomething(request, response);
    }
}

public class MyObject {
    private MyOtherObject myOtherObject = new MyOtherObject();
    public void doSomething(ServletRequest request, ServletResponse response) {
        // I do nothing with request/response, but need to accept them in order
        // to pass them to myOtherObject
        myOtherObject.doSomethingElse(request, response);
    }
}

public class MyOtherObject {
    public void doSomethingElse(ServletRequest request, ServletResponse response) {
        // Do something else with request / response
    }
}

Example 2: with thread local

public class MyServlet extends Servlet {
    private MyObject myObject = new MyObject();

    private static ThreadLocal<ServletRequest> currentRequest = new ThreadLocal<ServletRequest>();

    public static ServletRequest getCurrentRequest() {
        return currentRequest.get();
    }

    private static ThreadLocal<ServletResponse> currentResponse = new ThreadLocal<ServletResponse>();

    public static ServletResponse getCurrentResponse() {
        return currentResponse.get();
    }

    public void service(ServletRequest request, ServletResponse response) {
        ...
        currentRequest.set(request);
        currentResponse.set(response);
        ...
        myObject.doSomething();
    }
}

public class MyObject {
    private MyOtherObject myOtherObject = new MyOtherObject();
    public void doSomething() {
        // I do not need to know about request / response as I do nothing with them
        myOtherObject.doSomethingElse();
    }
}

public class MyOtherObject {
    public void doSomethingElse() {
        // Now I can get the current request / response in a thread safe
        // manner and without having to accept them as parameters
        ServletRequest request = MyServlet.getCurrentRequest();
        ServletResponse response = MyServlet.getCurrentResponse();

        // Do something with request / response
    }
}

Obviously, for simple servlets just passing the objects around is the easiest thing, but in complex scenarios it is sometimes useful to have one static but thread safe getter.

like image 80
gpeche Avatar answered Oct 17 '22 01:10

gpeche