[ Team LiB ] Previous Section Next Section

Recipe 11.8 Using URL Rewriting in a Servlet

Problem

You want to create a servlet that uses URL rewriting if the user has disabled cookies in his browser.

Solution

Use the HttpServletResponse.encodeURL(String url) method to encode all URLs that are used to link with other pages.

Discussion

The javax.servlet.HttpServletResponse class includes a nifty method that will encode a URL with the current session ID, in the event that the user making the servlet request has disabled cookies.

In fact, if you use the HttpServletResponse.encodeURL(String url) method to encode the URLs that are used in a servlet, this method takes care of URL rewriting if necessary, and you won't have to worry about whether cookies are enabled in users' browsers. You must conscientiously encode every URL link involved with the servlet when using this method. Example 11-13 is a servlet version of the example used in Recipe 11.6.

Example 11-13. Using URL rewriting in a servlet
import javax.servlet.*;
import javax.servlet.http.*;

public class UrlRewrite extends HttpServlet {
  
 public void doGet(HttpServletRequest request, 
   HttpServletResponse response)
    throws ServletException, java.io.IOException {
        
        response.setContentType("text/html");
        java.io.PrintWriter out = response.getWriter( );

        String contextPath = request.getContextPath( );

        String encodedUrl =  response.encodeURL(contextPath +
        "/default.jsp");
       
        out.println("<html>");
        out.println("<head>");
        out.println("<title>URL Rewriter</title>");  
        out.println("</head>");
        out.println("<body>");
        out.println(
        "<h1>This page will use URL rewriting if necessary</h2>");

        out.println("Go to the default.jsp page <a href=\"" + encodedUrl + 
            "\">here</a>.");

        out.println("</body>");
        out.println("</html>");
  } 

 public void doPost(HttpServletRequest request, 
   HttpServletResponse response)
    throws ServletException, java.io.IOException {

     doGet(request,response);
 }
}

In the page that is sent to the browser with cookies disabled, the URL looks like: /home/default.jsp;jsessionid=3CAF7CD0A0BFF5076B390CCD24FD8F0D.

One of the differences between using encodeURL and the JSP solution in Recipe 11.7 (which used the url custom action from the JSTL) is that the custom action in JSTL 1.0 will automatically prepend the context path to the URL. If the context path was /home, and the URL was /default.jsp, then the rewritten URL would look like /home/default.jsp;jsessionid=3CAF7CD0A0BFF5076B390CCD24FD8F0D. Automatically adding the context path in this manner to the URL is a separate operation compared with URL rewriting; it is not performed by the encodeURL method. If you want to duplicate this operation with a servlet, add the context path to the URL before calling the encodeURL method, as in:

String contextPath =request.getContextPath( );
        String encodedUrl = response.encodeURL(contextPath + "/default.jsp")


You can also use the related HttpServletResponse.encodeRedirectURL( String url) method to initiate URL rewriting with calls to HttpServletResponse.sendRedirect( String url). The servlet doGet( ) method in Example 11-14 uses encodeRedirectURL to ensure that the destination URLs have access to the session ID of the redirected user.

Example 11-14. Using encodeRedirectURL in a servlet doGet method
public void doGet(HttpServletRequest request, HttpServletResponse response) throws 
ServletException, java.io.IOException {
        
       //redirect the user depending on the value of the go param
        String destination = request.getParameter("go");
        String contextPath = request.getContextPath( );
        
         if(destination == null || destination.equals(""))
            throw new ServletException(
             "Missing or invalid 'go' parameter in " +
               getClass( ).getName( ));
        
        if(destination.equals("weather")){
        //ensure URL rewriting
            response.sendRedirect( 
              response.encodeRedirectURL(
                contextPath + "/weather") );}
        
         if(destination.equals("maps")){
        //ensure URL rewriting
            response.sendRedirect( 
              response.encodeRedirectURL(
                contextPath + "/maps") );}
    }

The response.sendRedirect(String url) method redirects the request to the destination represented by its url parameter. The server sends an HTTP status message to the client:

HTTP/1.1 302 Moved Temporarily

Additionally, a Location response header is sent along that provides the client with the new URL for the requested file. If necessary, the response.encodeRedirectURL(String url) method adds the session ID to the redirect destination of this URL. The example gets the name of a servlet from the value of the request's go parameter:

String destination = request.getParameter("go");

The servlet throws a ServletException if the parameter is either missing or is an empty String. If the go parameter is valid, the servlet redirects the request to one of two servlets, with paths of /weather or /maps (the context path in the example is /home). If implemented properly on the server, the following code adds the session ID to the URL if the requester's cookies are disabled, so the destination servlet can initiate session tracking:

response.sendRedirect( response.encodeRedirectURL(contextPath + "/weather") );

See Also

Recipe 11.4 on checking the validity of a session; Recipe 11.7 on using URL rewriting in a JSP; Chapter 1 on web.xml; Chapter 7 of the Servlet v2.3 and 2.4 specifications on sessions; the javax.servlet.http.HttpSession API at http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpSession.html; the session-tracking sections of Java Servlet Programming by Jason Hunter (O'Reilly) and JavaServer Pages by Hans Bergsten (O'Reilly).

    [ Team LiB ] Previous Section Next Section