What is a life of HttpServletRequest object? - java

I have doubt about HttpServletRequest life object. Is the request object destroyed after it got into controller?

The lifetime of an HttpServletRequest object is just that: the time of serving an HTTP Servlet request.
It may be created right before calling the servlet's doGet(), doPost() etc. methods, and may be destroyed right after that. It is only valid to use it during serving a request.
Note: However Servlet containers may reuse HttpServletRequest objects for multiple requests (and this is typically the case), but they will be "cleaned" or reset so no objects (like parameters or attributes) will leak between requests. This is simply due to performance issue: it is much faster and cheaper to reset an HttpServletRequest object than to throw away an existing one and create a new one.
In a typical Servlet container implementation if an HTTP request comes in, an HttpServletRequest is created right when the HTTP input data of the request is parsed by the Servlet container. The whole request might be lazily initialized (e.g. parameters might only be parsed and populated if they are really accessed e.g. via getParameter() method). Then this HttpServletRequest (which extends ServletRequest) is passed through the Servlet filters and then passed on to Servlet.service() which will dispatch the call to doGet(), doPost() etc based on the HTTP method (GET, POST, PUT etc.). Then the request will still be alive until the request-response pair cycles back throughout the filter chain. And then it will be destroyed or reset (before it is used for another HTTP request).

Related

Risk of injecting an HttpServletRequest class into a Service class

I am injecting the HttpServletRequest class into a class with the #Service annotation passing the instance of the HttpServletRequest class to a utility class (AuthorizationUtils) to get the authorization header. Is there any risk in this, such as my AuthorizationUtils trying to call the method below and my service class or HttpServletRequest class already being destroyed?
request.getHeader("Authorization")
I would avoid doing that (for architectural reasons), but no, there is no risk.
What would be incorrect would be to pass the request to a separate thread (or an async method, which is executed in a separate thread). Not because the class would be "destroyed" (that doesn't exist), but because the specification says:
Each request object is valid only within the scope of a servlet’s service method. [...] Containers commonly recycle request objects in order to avoid the performance overhead of request object creation. The developer must be aware that maintaining references to request objects for which startAsync has not been called outside the scope described above is not recommended as it may have indeterminate results.
If your service is synchronous, then the service() method of the servlet hasn't returned yet when your service method is executed, so that's fine.

What are "programmatic server-side includes"?

From the Java EE tutorial:
If the resource is static, the include method enables programmatic server-side includes.
If the resource is a web component, the effect of the method is to send the request to the included web component, execute the web component, and then include the result of the execution in the response from the containing servlet.
I'm not quite sure what they mean by "programmatic server-side includes" and how those differ from the web component case.
I mean, regardless of the resource I include, I pass a request/response object tuple to it and get some side-effects that I may or may not communicate to the client, right?
Could somebody please elaborate on this?
You've omitted the heading and text preceding your quotation. These provide important context for the comments you're asking about:
Including Other Resources in the Response
It is often useful to include another web resource, such as banner
content or copyright information, in the response returned from a web
component. To include another resource, invoke the include method of a
RequestDispatcher object:
include(request, response);
Thus, when the comments continue with
If the resource is static, the include method enables programmatic server-side includes.
they are characterizing the effect of the preceding code snippet, not introducing some new concept. A "programmatic server-side include" in this context is invoking the include() method of a RequestDispatcher() associated with a static resource. It has the effect of including the resource associated with the dispatcher, inline in the response being prepared. As such, this is "server-side" because it is all done by the server, transparently to the client, as opposed to the client having to make a separate request for the included resource.*
The distinction between the static and web component cases is about the resource associated with the RequestDispatcher on which that include() method is invoked -- i.e. what resource is to be included -- not about the component whose code contains the method invocation. A static resource is exactly a resource that can be identified by a URL that is not associated with a web component. Normally this means it corresponds to a file. The file content could be anything, but a common use is for it to comprise an HTML fragment, such as a header or footer shared by many web pages.
I mean, regardless of the resource I include, I pass a
request/response object tuple to it and get some side-effects that I
may or may not communicate to the client, right?
It's more accurate to view it as passing a request and response object to the RequestDispatcher. In the event that the dispatcher is associated with a static resource, no, the request and response objects are not presented to that resource (itself) because it has no mechanism for receiving or manipulating them. Instead, the servlet engine in which the code runs manipulates the response object as it decides is appropriate.
In the event that the target resource is a web component, yes, it will be able to read data from the provided request, manipulate the request and its context, and manipulate the provided response, all at its discretion. Generally, it cannot distinguish this case from the one in which it is accessed directly. But no, the component invoking include() has at best limited control over what is communicated to the client via that mechanism.
*For more information on the history of and inspiration for the "server-side includes" part of the term, consult Wikipedia.

Confusion regarding the behaviour of the request object

I've been messing around with servlets and JSPs and I am a bit confused at something:
I've made a servlet (controller) which would dispatch the request to a JSP
I've set some attributes to the request object using setAttribute() method in my
servlet.
I can access the request object's parameters and attributes within the JSP without any
problem.
Now I've stored the request object as an attribute in the session object using
session.setAttribute("test", request).
I've written a second JSP (navigating to it from the first JSP would be through
Javascript when I click a particular button- by using the window.location function and
giving the address of the second JSP as the value)
In the second JSP, when I retrieve the request object from the session object, I get a
null value from all the attributes of the retrieved request object.
I can access the parameters of the retrieved request object BUT only if I had retrieved
the parameters atleast once in my first JSP using request.getParameter() method
otherwise they return null in my second JSP.
I am really new to this stuff and am confused about this behaviour. Why were my request object's attributes being 'erased' while the parameters remain intact (as long I had accessed the parameters in my first JSP; which is even more bewildering to me as it does not make sense IMO)
Any explanation would be appreciated! Thanking you in advance.
This is just an educated guess, but I think the problem is that request objects in your container of choice might be lazy about its parameters: when you ask it for a parameter it reaches out to some external context and pulls the required data, at the same time caching it.
Nevertheless, the reason of the strange behavior is not really important. The problem should be solved by not saving requests in session. A request object is only your handle to the current request, not a data store by itself. It might be using any mechanism underneath, for all we know the attributes may be stored in threadlocals. There is absolutely no contract that would make a request act as an archive of any sort. For example: what would it mean if I asked such a stored request for the security principal? Would I mean "the current principal of the session"? Would I mean "the principal as of the moment when the request was created"?
EDIT:
Out of pure curiosity I just took a peek at Tomcat's implementation (I have no idea which container you are using) and found that it supports my claims: not only most of the data is gathered lazily, but the request object is recycled! So if you try store it in a session and then use, you might find that you are using someone's else request.
There are 4 scopes in Java EE 5. In both Java EE 6 and Java EE 7 there are 5 scopes. The most used are:
Request scope
Session scope
Application scope (Web Context)
You can store some data in all the above scopes by setting the appropriate attribute.
Here is a quote from the Java EE API docs related to ServletRequest.setAttribute(String, Object) method in regard to request scope:
void setAttribute(java.lang.String name,
java.lang.Object o)
Stores an attribute in this request. Attributes are reset between
requests. This method is most often used in conjunction with
RequestDispatcher.
...
So with every new request the previous attributes you have set in request will be lost. After you have set an attribute in a request, you must forward the request to the desired page. If you redirect, this will be a totally NEW request, thus the attributes previously set will be lost. (If you still want use redirection read this: Servlet Redirection to same page with error message)
Those attributes that are set in a HttpSession (in the session scope) will live as long as the session lives and, of course, will be available to only the user to which session belongs.
As for the context attributes they are meant to be available to the whole web application (application scope) and for ALL users, plus they live as long as the web application lives.
As a conclusion, if you have previously set an attribute in the session it will be available to the same user as long as the session is alive.
Hope this will help you.
P.S.
Maybe this article will also be useful for you: How Java EE 6 Scopes Affect User Interactions
The only thing that this article uses Annotations for scoping, but you'll get the idea.

Detect calls to RequestDispatcher.include()

I am programming a Servlet-Filter, that wraps the response and analyzes calls to addHeader() of the wrapped response. Before the response is committed to the client, it decorates it with some usefull headers (caching,compression etc), if appropriate.
This decoration is done, when ServletResponse.flushBuffer() is called on the wrapped response, or when the buffer-size is reached. But if the wrapped Servlet (or JSP-Page) is processing an include at that moment, no headers can be added to the response, because an include is forbidden to do that.
Therefore, I need to detect includes, so that I am able, to decorate the repsonse before the ressource is included.
The only way, I can think of, to accomplish that is, to wrap the request, catch calls to ServletRequest.getRequestDispatcher() and return a wrapped instance of RequestDispatcher, that informs me, when it's include-method is called. But since Servlet 3.0 there are also the methods ServletContext.getRequestDispatcher() and ServletContext.getNamedDispatcher(). I cannot catch that methods, because my filter cannot wrap the ServletContext.
Is there any other way to detect calls to RequestDispatcher.include()?
adding
<dispatcher>INCLUDE</dispatcher>
to filter-mapping seems to work refer

Methods a subclass of HttpServlet override

I have read in HttpServlet documentation that
A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
What rule that helps compiler in checking that any one of the above method is overrided in subclass?
Nothing. You (actually, the enduser) will just face a HTTP 405 Method Not Implemented error when requesting the servlet using a non-overridden HTTP method, because that's what the default implementation does.
All of those methods are protected. The compiler can't require that the subclass override "at least one of them".
It just wouldn't make sense not to, because you would have a "not implemented explosion" servlet.

Categories

Resources