(I'm not sure exactly how to phrase the title here, and because of that I'm not really sure how to go about searching for the answer either.)
I have a Java servlet engine that handles requests. Say we have a doGet()
request:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//set up user data
//do whatever the user requested
SomeClass c = new SomeClass();
c.doSomething();
}
Now in doSomething()
, I want to be able to access which user made the request. Right now I'm doing it by creating a Java object within the method and passing it to wherever I need it:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//set up user data
MyUserObj userObj = new MyUserObj();
userObj.setId('123');
//do whatever the user requested
SomeClass c = new SomeClass(userObj);
c.doSomething();
}
By doing this, I have access to the instance of MyUserObj
, and it can be further passed along in the application as needed.
I know in ASP.NET MVC3 I can acheive this by storing items/attributes for the current thread like this: HttpContext.Current.Items.Add("myId", "123")
. HttpContext
is then available in other functions without explicitly having to pass around an object.
Is there a way in Java to set some variables per request (or even set the MyUserObject
to be accessed later) without passing the object through as a parameter?
java.lang.Object | +--oracle.soap.server.RequestContext public class RequestContext extends java.lang.Object. RequestContext defines all of the context for a SOAP request, including information that is passed to the provider and information that the provider must set before returning.
servlet. http packages represent interfaces and classes for servlet api. The javax. servlet package contains many interfaces and classes that are used by the servlet or web container.
Defines a generic, protocol-independent servlet. To write an HTTP servlet for use on the Web, extend HttpServlet instead. GenericServlet implements the Servlet and ServletConfig interfaces. GenericServlet may be directly extended by a servlet, although it's more common to extend a protocol-specific subclass such as HttpServlet .
Servlet API provides HttpServlet class in javax.servlet.http package. An abstract class to be subclassed to create an HTTP-specific servlet that is suitable for a Web site/Web application. Extends Generic Servlet class and implements Serializable interface.
JspAwareRequestContext public class RequestContextextends Object Context holder for request-specific state, like current web application context, current locale, current theme, and potential binding errors. Provides easy access to localized messages and Errors instances.
HTTP Protocol-dependent servlet. To write a Http servlet, you need to extend javax.servlet.http.HttpServlet class and must override at least one of the below methods, doGet () – to support HTTP GET requests by the servlet.
There isn't in the servlet API, but you can make your own pretty easily. (Some frameworks like spring-mvc, struts provide such functionality)
Just use a public static ThreadLocal
to store and retrieve the object. You can even store the HttpServletRequest
itself in the threadlocal and use its setAttribute()
/getAttribute()
methods, or you can store a threadlocal Map
, to be agnostic of the servlet API. An important note is that you should clean the threadlocal after the request (with a Filter, for example).
Also note that passing the object as parameter is considered a better practice, because you usually pass it from the web layer to a service layer, which should not be dependent on web-related object, like a HttpContext
.
If you decide that it is fine to store them in a thread-local, rather than passing them around:
public class RequestContext {
private static ThreadLocal<Map<Object, Object>> attributes = new ThreadLocal<>();
public static void initialize() {
attributes.set(new HashMap<Map<Object, Object>>());
}
public static void cleanup() {
attributes.set(null);
}
public static <T> T getAttribute(Object key) {
return (T) attributes.get().get(key);
}
public static void setAttribute(Object key, Object value) {
attributes.get().put(key, value);
}
}
And a necessary filter:
@WebFilter(urlPatterns="/")
public class RequestContextFilter implements Filter {
public void doFilter(..) {
RequestContext.initialize();
try {
chain.doFilter(request, response);
} finally {
RequestContext.cleanup();
}
}
}
You can attach an object to the current request with setAttribute
. This API is primarily used for internal routing, but it's safe to use for your own purposes too, as long as you use a proper namespace for your attribute names.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With