Saturday, June 21, 2008

Difference between forward and sendRedirectforward - public void forward(ServletRequest request ServletResponse response) - it forwards a request from one servlet to another respource - dynamic/static (the resource can be another servlet, JSP, or a static HTML file). In such a case, the calling servlet only does the preliminary work for the request processing and doesn't usually write anything on the response object. Writing anything on the response object in the calling servlet will result into an IllegalStateException for the forward() call if the output is flushed already otherwise the uncommitted response buffer is cleared before the forward() call. This action is performed internally by the Servlet (or JSP which actually converts into a Servlet only) and the client browser is not at all involved in it. Client browser is simply unaware of it and the URL remain intact. Hence, any refresh/reload in the client browser will simply repeat the same request. This is the reason why a forward should not be used for serving a request involving some data modification as an accidental refresh/reload of the browser may duplicate that change. forward() is usually preferred in the cases where we simply read the data i.e., in the cases where we use SELECT operation.

The same request and response objects are passed as parameters to the forward() call hence the called resource can use all the objects defined in the request scope of the previous request. Passed response object gets cleared (if the calling servlet has written something before the forward() call) and hence it remains empty for the new resource and the called resource builds the response object which it ultimately sends to the client.

We can specify the resource with a relative URL only for a forward action. forward() called on a RequestDispatcher obtained from an objet of the class implementing ServletRequest interface accepts an URL relative either to the underlying request or to the underlying servlet context. Whereas forward() called on an RequestDispatcher obtained from a ServletContext implementation will require you to specify an URL only relative to the underlying context. Read more about this - RequestDispatcher of ServletRequest & ServletContext >>. We can NOT specify an absolute URL in forward() method.sendRedirect - public void sendRedirect(java.lang.String location) - in this case first the request is intercepted/processed by the server and then a new URL is built and sent back to the client (this new URL is built using the URL what we specify in the sendRedirect method). We can specify either a relative URL or an absolute URL. If a relative URL if specified without a leading '/' then the Container interprets it as being relative to the current request whereas a relative URL with a leading '/' is interpreted as being relative to the underlying context. The Container interprets the relative URL and converts it into an absolute URL before sending it back to the client. Now the newly constructed URL is again requested from the client. This URL change is quite visible in the client browser.Thus we see that sendRedirect is basically a two phase process and hence it's slightly slower than forward() method. Since, the new URL is requested as an altogether new request hence the objects placed in the previous request scope can't be accessed in the new request.

Unlike the forward() method, an accidental (or intentional) refresh/reload of browser window will not repeat the original request. Only the new URL will be requested in this case as the browser's address bar is already updated with the new URL. Hence, the operation involving modification should prefer sendRedirect() over forward() to avoid any accidental duplicacy.

Example: affect of accidental refresh/reload on forward() and sendRedirect()Suppose the first request takes you to a page requesting you to transfer some funds online and then the second resource just notifies whether the transfer was done successfully or not. In case of a forward() call, an accidental refresh/reload of the browser window will execute the original request of transferring the fund again (as the browser has still the original URL) and then the status page will be shown. That means both the resources will again be executed and you may ned up transferring the fund twice :-) In case of sendRedirect(), the processing of the original transfer request will redirect the status URL to the client browser and hence an accidental (or maybe intentional) refresh/reload will only execute the resource (maybe a JSP) showing you the status of the previous transfer and that's what you would probably like to have. sendRedirect() avoids the execution of the original request again because in this case the browser's address bar is already updated with the new URL.

Difference between forward() and sendRedirect()

forward() call is unknown to the client browser and nothing is visible in the URL whereas sendRedierct() makes the new URL visible.

forward() accepts only relative URLs (either relative to the request or relative to the context) whereas sendRedirect() can accepts relative URLs (which are converted into absolute URLs by the Container) as well as absolute URLs.

forward() is slightly faster than sendRedirect() as it avoid an extra phase of sending the new URL back to the client browser and getting it requested from there as a new request.

forward() can use the objects in the request scope as the same request is passed as the parameter to the forwarded resource whereas in case of sendRedirect() the call is treated as a new request and hence can't use the previous request scope.

forward() is preferred for SELECT operations requiring no modification to avoid the duplicacy caused by an accidental refresh/reload of the clinet browser window as a refresh causes the same original request to be processed again whereas sendRedirect() is preferred for INSERT/UPDATE kind of operations which actually modify some state.