I am reading the OCEJWCD Study companion chapter 6 and I came across the topic which talks about additional request attributes that are set by the container when you call forward/include method on a RequestDispatcher instance.
The book says that the various paths in request object are updated by the container on calling forward/include to reflect the path of the resource included or forwarded. It also states that the path of the original servlet making this call is stored in the request as special attributes. However, I found that this doesnt agree with the execution results. I am using Tomcat 7.0.42
In case I call forward, I see that the paths in the request object passed to the forwarded resource reflects that of the resource itself and the attributes are set to reflect the path of the original servlet that made the call. However, in case of include, I noticed that when I access the path information from the included resource, the path still reflects the original servlet that made the call and not the included resource. However, the additional request attributes were holding the included resource path information. So basically, here the information got swapped between the request object paths and the attributes.
Which one is correct? Logically, the execution results seem correct to me. I check the book's errata but couldnt find anything related to this.
Did anybody try this and found similar results?
Another discrepancy I found is as follows:
As per the book, ServletException can be either temporary or permanent but UnavailableException is always permanent. However the API has two constructors for UnavailableException one for temporary and one for permanent whereas the ServletException doesn't have any constructor for indicating that this is a temporary. Which one is correct?
Lastly, whats the difference between HttpServletResponse.flushBuffer() and PrintWriter.flush() (latter is obtained from the former)
I will try to give you some of the answers:
Question 1 Which one is correct? Logically, the execution results seem correct to me. I check the book's errata but couldnt find anything related to this.
The answer lies in the Servlet 3.0 specs:
9.4.2 Forwarded Request Parameters Except for servlets obtained by using the getNamedDispatcher method, a servlet that has been invoked by another servlet using the forward method of RequestDispatcher has access to the path of the original request.
The following request attributes must be set:
The values of these attributes must be equal to the return values of the HttpServletRequest methods getRequestURI, getContextPath, getServletPath, getPathInfo, getQueryString respectively, invoked on the request object passed to the first servlet object in the call chain that received the request from the client. These attributes are accessible from the forwarded servlet via the getAttribute method on the request object. Note that these attributes must always reflect the information in the original request even under the situation that multiple forwards and subsequent includes are called.
If the forwarded servlet was obtained by using the getNamedDispatcher method, these attributes must not be set.
9.3.1 Included Request Parameters Except for servlets obtained by using the getNamedDispatcher method, a servlet that has been invoked by another servlet using the include method of RequestDispatcher has access to the path by which it was invoked. The following request attributes must be set:
These attributes are accessible from the included servlet via the getAttribute method on the request object and their values must be equal to the request URI, context path, servlet path, path info, and query string of the included servlet, respectively. If the request is subsequently included, these attributes are replaced for that include.
If the included servlet was obtained by using the getNamedDispatcher method,
these attributes must not be set.
188.8.131.52 Exceptions During Request Handling A ServletException signals that some error occurred during the processing of the request and that the container should take appropriate measures to clean up the request.
An UnavailableException signals that the servlet is unable to handle requests either temporarily or permanently.
Question 3 Lastly, whats the difference between HttpServletResponse.flushBuffer() and PrintWriter.flush() (latter is obtained from the former)
The HttpServletResponse.flushBuffer() flushes the buffer and also commits the response: "Forces any content in the buffer to be written to the client. A call to this method automatically commits the response, meaning the status code and headers will be written. "
The PrintWriter.flush() just flushes buffered output to the underlying stream.
I guess you won't notice any difference in behaviour in a Servlet, or did you?
Thanks a ton Frits. You not only gave me the answers I was looking for but also guided me to the right place where to look for answers - the spec. It is indeed very helpful and now I mostly look there for answers. Sadly, you cant rely on the words of the book if they are not clear to you.
Maybe Charles can fix this up in the next edition or include this in errata.