Get the HttpServletRequest (request) object from Java code - java

I need to get hold of the request object in Java code. I can't pass this object down to my code for certain reasons. Is there any way I can say something like: getCurrentHTTPServletRequest?
It is safe for me to assume that I am in a Servlet Context.

Well you should pass it down if you need it. Anything else you do is going to be ugly, basically.
You could use a ThreadLocal variable - basically set the context for that particular thread when you get the request, and then fetch it later on. That will work so long as you only need to get at the request within the thread that's processing it - and so long as you don't do any funky asynchronous request handling. It's brittle though, for precisely those reasons.
However, I would strongly advise you to be explicit about your dependencies instead. Either pass the servlet request down, or just the bits that you need.

Assuming you're not able to pass the request object down the call stack, then some kind of sharing mechanism becomes necessary, which is not ideal, but sometimes necessary.
Spring provides the RequestContextFilter for just this purpose. It uses ThreadLocal, and allows the code to fetch the current request via RequestContextHolder. Note that this filter does not require you to use any other part of Spring:
Servlet 2.3 Filter that exposes the
request to the current thread, through
both LocaleContextHolder and
RequestContextHolder. To be registered
as filter in web.xml.
This filter is mainly for use with
third-party servlets, e.g. the JSF
FacesServlet. Within Spring's own web
support, DispatcherServlet's
processing is perfectly sufficient.
If you're going to use ThreadLocal, then better to use an existing, working solution, rather than risk bugs creeping in, which ThreadLocal code is prone to.

Jon Skeet said practically everything, but one clarification to his advice "just the bits that you need" - if you need your request parameters passed down, but you don't need a dependency on HttpServletRequest, pass request.getParameterMap().
And extending a bit on the ThreadLocal option - you can have a Filter which handles all incoming requests, and sets the request in a
public final static ThreadLocal<HttpServletRequest> httpServletRequestTL =
new ThreadLocal<HttpServletRequest>();
Because you are setting it on each request (careful with the filter mapping), you won't have to worry about the servlet-container thread pool - you will always have the current request.
P.S. this is the logic behind the spring utility proposed by skaffman - I join him recommending the stable component, rather than making your own.

There is no servlet API to do this. However, Tomcat does provide an API call to do this,
HttpServletRequest request = (HttpServletRequest)org.apache.catalina.core.ApplicationFilterChain.getLastServicedRequest();
This will get the last request passed to a servlet for servicing from the current thread.
For this to work, the Tomcat must be in "Strict Servlet Compliance" mode. If not, you need to enable it by adding this JVM parameter:
org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true

Assuming the top-level servlet really is taboo for some crazy business-related reason, there is still the option of defining a ServletFilter to pre-view the request and stuff it into a ThreadLocal. Assuming that the web.xml is not also sacrosanct.
But I agree with Jon Skeet in that this would be very ugly. I'd code this up and then try to find a different job. :)
Actually, given the fact that a filter can totally wrest away control from the receiving servlet, you could use this technique to divert the code to a servlet of your own, do whatever you want, and THEN run the other, "official" servlet... or anything else along those lines. Some of those solutions would even allow you to deal correctly and robustly with your request data.

Related

How to make a GAE server repeat operation?

If I want to update a cache every minute, or do something else every hour, where I should put my code (Java) ? As I think, not in the servlets. Can you help me with it?
You need to use cron jobs:
Scheduled Tasks With Cron for Java
This is exactly what they have been designed for.
The answer by Andrei Volgin is correct, and you need to pursue the link.
However, I want to address the 'not in the servlets' part of your questions. I think you are asking from a design perspective whether the code should reside inside the servlet class. I have answered this for myself recently.
The way Crons and Tasks are implemented by GAE, the code will be called via servlets, as these are background URL calls. So, theoretically, the code can be in the servlet class itself. If you are using a framework like Spring, you will probably have one entry point servlet and your own handlers/managers/services. In this case, you can write the code in the handler.
In my project, I created a single entry point servlet for all UI related processing. When I needed to implement the first Task Queue I created another entry point servlet for the queues/crons and then coded inside new handlers.
In general, your app design would be looking similar to
UI ---> Servlet Entry Point 1 ---> Generic Business Logic Handler ---> Specific Business Logic Handler --> System Services Handler ---> System Services
Instead of UI, now we have Queues/Crons calling the system, but generally, as was in my case, the cron was calling code that was more 'internal', for example, send-mail is implemented as a queued task which needs to directly call the System Service Handler bypassing two business logic layers. Similarly, ftp-today's-transactions is a cron that needs to directly call System Services bypassing the business logic layers.
It makes sense to NOT directly call System services from servlet entry point 1, just because you happen to have it at hand and configured in web.xml. It makes more sense to create another entry point for queues and crons which are more 'internal'.
The code then resides in the next level class (called Handlers, sometimes) And you can continue to maintain the hierarchy of layers if you are using packages to enforce it.
You will then not feel bad about calling something sys level directly from servlet level as this will be a specifically secure and separate access interface defined to be calling direct.
Just to make it more intuitive, my two servlets are called
Thin - Thin Http Interface on NudeBusinessObjects [All BOs extend this, and there is a non Http interface]
Thiq - Thiq Http Interface on Queues
Thin just ensures the required parameters are present and passes to handler. It always calls com.mybusiness classes which in turn call com.mysystem classes if they need to.
Thiq has more code, needs secure credentials even on automatic, does more complicated validations and generally has defined high level behaviour for failures across crons/tasks. It always calls com.mysystem classes.
Just my two cents. It isn't too big a thing and if you only keep one entry point and achieve the same effect by writing things in handlers, or even servlets, it doesn't cause end of the world. It just looks ugly when you make an architecture diagram.

Is it a bad practice to use a ThreadLocal Object for storing web request metadata?

I am working on a j2ee webapp divided in several modules. I have some metadata such as user name and preferences that I would like to access from everywhere in the app, and maybe also gather data similar to logging information but specific to a request and store it in those metadata so that I could optionally send it back as debug information to the user.
Aside from passing a generic context object throughout every method from the upper presentation classes to the downer daos or using AOP, the only solution that came in mind was using a threadlocal "Context" object very similar to a session BTW, and add a filter for binding it on ongoing request and unbinding it on response.
But such thing feels a little hacky since this breaks several patterns and could possibly make things complicated when it comes to testing and debugging so I wanted to ask if from your experience it is ok to proceed like this?
ThreadLocal is a hack to make up for bad design and/or architecture. It's a terrible practice:
It's a pool of one or more global variables and global variables in any language are bad practice (there's a whole set of problems associated with global variables - search it on the net)
It may lead to memory leaks, in any J2EE container than manages its threads, if you don't handle it well.
What's even worse practice is to use the ThreadLocal in the various layers.
Data communicated from one layer to another should be passed using Transfer Objects (a standard pattern).
It's hard to think of a good justification for using ThreadLocal. Perhaps if you need to communicate some values between 2 layers that have a third/middle layer between them, and you don't have the means to make changes to that middle layer. But if that's the case, I would look for a better middle layer.
In any case, if you store the values in one specific point in the code and retrieve it in another single point, then it may be excusable, otherwise you just never know what side affects any executing method may have on the values in the ThreadLocal.
Personally I prefer passing a context object, as the fact that the same thread is used for processing is an artifact of the implementation, and you shouldn't rely on such artifacts. The moment you want to use other threads, you'll hit a wall.
If those states are encapsulated in a Context object, I think that's clean enough.
When it comes to testing, the best tool is dependency injection. It allows to inject fake dependencies into the object under test.
And all dependency injection frameworks (Spring, CDI, Guice) have the concept of a scope (where request is one of these scopes). Under the hood, beans stored in the request scoped are indeed associated with a ThreadLocal variable, but this is all done by the dependency injection framework.
What I would do is thus to use a DI framework, which would make request-scope objects available anywhere, but without having to look them up, which would break testability. Just inject a request-scoped object where you want to use it, and the DI framework will retrieve it for you.
You must know that a servlet container can / will re-use threads for requests so if you do use ThreadLocals, you'll need to clean up after yourself once the request is finished (perhaps using a filter)
If you are the only developer in the project and you think you gain something: just do it! Because it is your time. But, be prepared to revert the decision and reorganize the code base later, as should be always the case.
Let's say there are ten developers on the project. Everybody might like to have its thread local variable to pass on parameters like currency, locale, roles, maybe it becomes even a HashMap....
I think in the end, not everything which is feasible, should be done. Complexity will strike back on you....
ThreadLocal can lead to memory leak if we do not set null manually once its out of scope.

How to determine JAX-RS resource paths programatically?

Suppose I have a set of JAX-RS locators and sublocators, like the following:
#Path("/users")
public class UserListResource {
#Path("/{id}")
public UserResource getCustomer(#PathParam("id") int id) {
// Find and return user object
}
}
public class UserResource {
#GET
public String get() {...}
}
For example, a UserResource object with the ID 5 would have the path "/users/5". In my system, I have several different resources.
Now the question is: How can the server figure out the path of a given resource? Can I do this programmatically via some JAX-RS API or do I have to implement code that uses reflection? (I know how to do the latter, but would prefer the other approach.)
At the point when I need to know the path, I do not have a request object at all. For example, I have a timer which does some background processing, then changes some entities in the domain model, then informs all clients about the changed entities (including their paths).
I know that within the scope of a request, I can inject a UriInfo object that provides this, but I need to know the path in advance (to inform clients of a change that did not necessarily happen through the JAX-RS resource).
I don't want to repeat the path information in another place, and I also don't want to have a set of path fragment constants for each resource type (in this case "/users" and "/{id}").
As I read your question, you need to build a URI knowing only the resource class and the id parameter.
It can be done using the UriBuilder class as in:
UriBuilder builder=UriBuilder.fromResource(UserListResource.class);
URI uri=builder.path(UserListResource.class,"getCustomer").build(5);
It uses reflection under the hood, so it is not so easy to refactor, but it is all it is available at the moment.
Overall, be aware that something sounds rather strange with the architecture of your application. It's hard to put a finger on, but the pattern of questions you are asking is raising a number of red flags about how you're going about this. Be aware that if you are seeking to create a RESTful API to your application that you may need to stop, take a few steps back, and rethink what you are trying to do.
To your explicit questions…
Now the question is: How can the server figure out the path of a given resource? Can I do this programmatically via some JAX-RS API or do I have to implement code that uses reflection? (I know how to do the latter, but would prefer the other approach.)
The server knows the path, as that's always supplied by the user and is used to navigate through the collection of resource classes that make up your application. If you need a UriInfo instance for a particular call, you should inject it as part of that specific call:
#GET
public String get(#Context UriInfo info) {...}
Any information required from the outer context (e.g., what the resource's ID is) is best passed in during construction. You can reparse it out of the URL (obtainable from the UriInfo) again, but that's probably the wrong approach.
Otherwise, if you're doing something much more complex then you need to be more specific in your question.
At the point when I need to know the path, I do not have a request object at all. For example, I have a timer which does some background processing, then changes some entities in the domain model, then informs all clients about the changed entities (including their paths).
I know that within the scope of a request, I can inject a UriInfo object that provides this, but I need to know the path in advance (to inform clients of a change that did not necessarily happen through the JAX-RS resource).
How are you going to have the clients be informed? There's normally no mechanism to push messages from the server to the clients, and clients are typically firewalled so that they can't directly host a service.
Theoretically, you could associate (explicitly, by URL) each resource with its own RSS feed to which a client could listen to if they chose. You wouldn't be able to force clients to listen, but you could give them the option to do so. If you go this route, you don't need to know the UriInfo “ahead of time” as the location information will be present at key times (i.e., at resource creation) and afterwards you're just referring to something that you have control over.
But that's just one way to do it and it adds a lot of complexity; you'd only do it if it was critical to your application. It's often simpler to just have clients poll from time to time. (Note that some sorts of modifications are inherently very destructive; particularly altering the ID or deleting the resource. Don't expect things to cope smoothly with those.)
I don't want to repeat the path information in another place, and I also don't want to have a set of path fragment constants for each resource type (in this case "/users" and "/{id}").
Tough. Repeating information in multiple places, provided you draw it consistently from a single source, is a common practice. There's nothing actually wrong with it.
As I understand your question, you want to know the path as the request is coming in but before it hits your resource; are you open to using Servlet Filters?
JAX-RS specific filters are only supported in 2.0
For the record: after I had posted the question, I thought about our architecture a bit more and came to the conclusion that sending URLS is not as useful as I thought. The application has to know some details about the application structure anyway:
Continuing the example above: even if the client did not know the URL pattern for individual users, it must assume that there is a list of users and know its URL; it also has hard-coded knowledge what dialog to display for editing a user etc.
So all in all, attempting to tell the client (most) URLs it needs is not worth the effort. Instead, we decided to go with a custom API definition file which includes data about the resource contents and their URL scheme. This file is used to generate the following:
the server-side resource classes with the correct JAX-RS annotations
a URL scheme specification document for other developers to code against
classes for our own client (including the URL know how, e.g. user with ID 5 has the URL ...), so we don't have to worry about inconsistencies between our client and server.
This approach has the following advantages:
The need for the server to figure out the URLs from the annotations vanishes, as the client can now do that on its own once it receives a notification that includes the object ID.
We don't have to worry about inconsistencies between our client and the server, as all information is drawn from a single source.
We have one source for the API definition under version control which can be used to verify backwards compatibility with older releases.
Note:
I would probably not claim that the resulting API stays "faithful" to the idea of RESTful webservices, but it works for us and the elements that it borrows from "actual" REST architectural style should make the API clearer and easier to learn than a traditional contract-first webservice.

Servlet 3 spec and ThreadLocal

As far as I know, Servlet 3 spec introduces asynchronous processing feature. Among other things, this will mean that the same thread can and will be reused for processing another, concurrent, HTTP request(s). This isn't revolutionary, at least for people who worked with NIO before.
Anyway, this leads to another important thing: no ThreadLocal variables as a temporary storage for the request data. Because if the same thread suddenly becomes the carrier thread to a different HTTP request, request-local data will be exposed to another request.
All of that is my pure speculation based on reading articles, I haven't got time to play with any Servlet 3 implementations (Tomcat 7, GlassFish 3.0.X, etc.).
So, the questions:
Am I correct to assume that ThreadLocal will cease to be a convenient hack to keep the request data?
Has anybody played with any of Servlet 3 implementations and tried using ThreadLocals to prove the above?
Apart from storing data inside HTTP Session, are there any other similar easy-to-reach hacks you could possibly advise?
EDIT: don't get me wrong. I completely understand the dangers and ThreadLocal being a hack. In fact, I always advise against using it in similar context. However, believe it or not, thread context has been used far more frequently than you probably imagine. A good example would be Spring's OpenSessionInViewFilter which, according to its Javadoc:
This filter makes Hibernate Sessions
available via the current thread,
which will be autodetected by
transaction managers.
This isn't strictly ThreadLocal (haven't checked the source) but already sounds alarming. I can think of more similar scenarios, and the abundance of web frameworks makes this much more likely.
Briefly speaking, many people have built their sand castles on top of this hack, with or without awareness. Therefore Stephen's answer is understandable but not quite what I'm after. I would like to get a confirmation whether anyone has actually tried and was able to reproduce failing behaviour so this question could be used as a reference point to others trapped by the same problem.
Async processing shouldn't bother you unless you explcitly ask for it.
For example, request can't be made async if servlet or any of filters in request's filter chain is not marked with <async-supported>true</async-supported>. Therefore, you can still use regular practices for regular requests.
Of couse, if you actually need async processing, you need to use appropriate practices. Basically, when request is processed asynchronously, its processing is broken into parts. These parts don't share thread-local state, however, you can still use thread-local state inside each of that parts, though you have to manage the state manually between the parts.
(Caveat: I've not read the Servlet 3 spec in detail, so I cannot say for sure that the spec says what you think it does. I'm just assuming that it does ...)
Am I correct to assume that ThreadLocal will cease to be a convenient hack to keep the request data?
Using ThreadLocal was always a poor approach, because you always ran the risk that information would leak when a worker thread finished one request and started on another one. Storing stuff as attributes in the ServletRequest object was always a better idea.
Now you've simply got another reason to do it the "right" way.
Has anybody played with any of Servlet 3 implementations and tried using ThreadLocals to prove the above?
That's not the right approach. It only tells you about the particular behaviour of a particular implementation under the particular circumstances of your test. You cannot generalize.
The correct approach is to assume that it will sometimes happen if the spec says it can ... and design your webapp to take account of it.
(Fear not! Apparently, in this case, this does not happen by default. Your webapp has to explicitly enable the async processing feature. If your code is infested with thread locals, you would be advised not to do this ...)
Apart from storing data inside HTTP Session, are there any other similar easy-to-reach hacks you could possibly advise.
Nope. The only right answer is storing request-specific data in the ServletRequest or ServletResponse object. Even storing it in the HTTP Session can be wrong, since there can be multiple requests active at the same time for a given session.
NOTE: Hacks follow. Use with caution, or really just don't use.
So long as you continue to understand which thread your code is executing in, there's no reason you can't use a ThreadLocal safely.
try {
tl.set(value);
doStuffUsingThreadLocal();
} finally {
tl.remove();
}
It's not as if your call stack is switched out randomly. Heck, if there are ThreadLocal values you want to set deep in the call stack and then use further out, you can hack that too:
public class Nasty {
static ThreadLocal<Set<ThreadLocal<?>>> cleanMe =
new ThreadLocal<Set<ThreadLocal<?>>>() {
protected Set<ThreadLocal<?>> initialValue() {
return new HashSet<ThreadLocal<?>>();
}
};
static void register(ThreadLocal<?> toClean) {
cleanMe.get().add(toClean);
}
static void cleanup() {
for(ThreadLocal<?> tl : toClean)
tl.remove();
toClean.clear();
}
}
Then you register your ThreadLocals as you set them, and cleanup in a finally clause somewhere. This is all shameful wankery that you shouldn't probably do. I'm sorry I wrote it but it's too late :/
I'm still wondering why people use the rotten javax.servlet API to actually implement their servlets. What I do:
I have a base class HttpRequestHandler which has private fields for request, response and a handle() method that can throw Exception plus some utility methods to get/set parameters, attributes, etc. I rarely need more than 5-10% of the servlet API, so this isn't as much work as it sounds.
In the servlet handler, I create an instance of this class and then forget about the servlet API.
I can extend this handler class and add all the fields and data that I need for the job. No huge parameter lists, no thread local hacking, no worries about concurrency.
I have a utility class for unit tests that creates a HttpRequestHandler with mock implementations of request and response. This way, I don't need a servlet environment to test my code.
This solves all my problems because I can get the DB session and other things in the init() method or I can insert a factory between the servlet and the real handler to do more complex things.
You are psychic ! (+1 for that)
My aim is ... to get a proof this has stopped working in Servlet 3.0 container
Here is the proof that you were asking for.
Incidentally, it is using the exact same OEMIV filter that you mentioned in your question and, guess what, it breaks Async servlet processing !
Edit: Here is another proof.
One solution is to not use ThreadLocal but rather use a singleton that contains a static array of the objects you want to make global. This object would contain a "threadName" field that you set. You first set the current thread's name (in doGet, doPost) to some random unique value (like a UUID), then store it as part of the object that contains the data you want stored in the singleton. Then whenever some part of your code needs to access the data, it simply goes through the array and checks for the object with the threadName that is currently running and retrieve the object. You'll need to add some cleanup code to remove the object from the array when the http request completes.

Java Filters Performance Question

I have two questions. The first is do Filters add a lot of overhead to request. We have a filter and it is set to run on the URL pattern /*. This means it also runs on all the image request. I think that this is not good for performance, but my co-workers think that it doesn't matter if the filter runs 5 or 6 times per request because the filter only has a couple of if statements.
Is there a way to have the filter run once per request, ignoring the image request.
Thanks Doug
Measuring is knowing. If well-written, I'd say, it's negligible. But if it's for example grabbing the session regardless of it's been created (and thus there's a chance that it will unnecessarily be created), then it may have a noticeable impact on performance and/or memory usage because creation of sessions isn't per-se cheap and sessions are stored in sever's memory for a longer term than the requests.
You may want to replace the url-pattern of /* by *.jsp or to move the restricted pages to a specific folder, e.g. /secured, /private, /pages, etc and alter the url-pattern accordingly to /secured/*, /private/*, /pages/*, etc and put all the static content in a different place, e.g. /static. This way the filter won't be invoked for static content anymore.
First, I agree with the Profile-first approach.
Second, as far as I know it depends, web-server use the same technique to invoke a specific servelt(/JSP) as they use for filters.
In case the filter is filtering a static resource(e.g. jpg file), it's a bit of a waste,
In case the filter is filtering a dynamic resource (e.g. Servlet) it's negligible..
(Most of the Java web frameworks like struts and Jboss-seam are using filters heavily..)
It almost never useful to speculate about the performance implications of code without first profiling it. Unless the code being proposed in the filters is doing some operations you know to be slow then measure first before optimising.
Remember even though when you are writing a servlet it may seem like the only thing that happens is the code in your doGet() or doPost() methods a lot of other things happen before your servlet/filter code gets invoked. The servlet container processes the HTTP request bundles it up in Java objects and does all sorts of other processing before it hands over to your code.
If your servlet filters really are only a couple of if statements operating on data that is cheap to get (such as the request itself), it is unlikely this is going to be an issue for you.

Categories