Section 3.4. Servlet Requests


3.4. Servlet Requests

When a servlet handles a request, it typically needs specific information about the request so that it can respond appropriately. Most frequently, a servlet retrieves the value of a form variable and uses that value in its output. A servlet may also need access to information about the environment in which it is running. For example, a servlet may need to authenticate the user who is accessing the servlet.

The ServletRequest and HttpServletRequest interfaces provide access to this kind of information. When a servlet is asked to handle a request, the servlet container passes it a request object that implements one of these interfaces. With this object, the servlet can determine the actual request (e.g., protocol, URL, type), access parts of the raw request (e.g., headers, input stream), and get any client-specific request parameters (e.g., form variables, extra path information). For instance, the getProtocol( ) method returns the protocol used by the request, while geTRemoteHost( ) returns the name of the client host. The interfaces also provide methods that let a servlet get information about the server (e.g., getServername( ), getServerPort( )). As we saw earlier, the getParameter( ) method provides access to request parameters such as form variables. There is also the getParameterValues( ) method, which returns an array of strings that contains all the values for a particular parameter. This array generally contains only one string, but some HTML form elements (as well as non-HTTP-oriented services) do allow multiple selections or options, so the method always returns an array, even if it has a length of 1.

HttpServletRequest adds a few more methods for handling HTTP-specific request data. For instance, getHeaderNames( ) returns an enumeration of the names of all the HTTP headers submitted with a request, while getHeader( ) returns a particular header value. Other methods handle cookies and sessions, as we'll discuss later.

Example 3-1 shows a servlet that restricts access to users who are connecting via the HTTPS protocol, using digest-style authentication and coming from a government site (a domain ending in .gov). The restrictions are implemented by checking information pulled from the servlet request using many of the methods described earlier.

Example 3-1. Checking request information to restrict servlet access
 import javax.servlet.*; import javax.servlet.http.*; import java.io.*;   public class SecureRequestServlet extends HttpServlet {     public void doGet(HttpServletRequest req, HttpServletResponse resp)     throws ServletException, IOException {       resp.setContentType("text/html");     PrintWriter out = resp.getWriter(  );       out.println("<html>");     out.println("<head><title>Semi-Secure Request</title></head>");     out.println("<body>");       String remoteHost = req.getRemoteHost(  );     String scheme = req.getScheme(  );     String authType = req.getAuthType(  );       if((remoteHost == null) || (scheme == null) || (authType == null)) {       out.println("Request Information Was Not Available.");       return;     }       if(scheme.equalsIgnoreCase("https") && remoteHost.endsWith(".gov")        && authType.equals("Digest")) {       out.println("Special, secret information.");     }     else {       out.println("You are not authorized to view this data.");     }       out.println("</body></html>");   } }

3.4.1. Forms and Interaction

The problem with creating a servlet like our earlier HelloWorldServlet is that it doesn't do anything we can't already do with HTML. If we are going to bother with a servlet at all, we should do something dynamic and interactive with it. In many cases, this means processing the results of an HTML form. To make our example less impersonal, let's have it greet the user by name. The HTML form that calls the servlet using a GET request might look like this:

 <html> <head><title>Greetings Form</title></head> <body> <form method=get action="/servlet/HelloServlet"> What is your name? <input type=text name="username" size=20> <input type=submit value="Introduce Yourself"> </form> </body> </html>

This form submits a form variable named username to /servlet/HelloServlet. The HelloServlet itself does little more than create an output stream, read the username form variable, and print a nice greeting for the user. Here's the code:

 import javax.servlet.*; import javax.servlet.http.*; import java.io.*;   public class HelloServlet extends HttpServlet {     public void doGet(HttpServletRequest req, HttpServletResponse resp)     throws ServletException, IOException {       resp.setContentType("text/html");     PrintWriter out = resp.getWriter(  );       out.println("<html>");     out.println("<head><title>Finally, interaction!</title></head>");     out.println("<body><h1>Hello, " + req.getParameter("username")                    + "!</h1>");     out.println("</body></html>");   } }

All we've done differently is use the getParameter( ) method of HttpServletRequest to retrieve the value of a form variable.[*] When a server calls a servlet, it can also pass a set of request parameters. With HTTP servlets, these parameters come from the HTTP request itselfin this case, in the guise of URL-encoded form variables. Note that a GenericServlet running in a web server also has access to these parameters using the simpler ServletRequest object. When HelloServlet runs, it inserts the value of the username form variable into the HTML output, as shown in Figure 3-2.

[*] For those interested in ancient history, in Java Web Server 1.1, the getParameter( ) method was deprecated in favor of getParameterValues( ), which returns a String array rather than a single string. However, after an extensive write-in campaign, Sun took getParameter( ) off the deprecated list for Version 2.0 of the Servlet API, so you can safely use this method in your servlets. This is not an issue with later versions of the API, and the fact that we even talk about it dates us.

Figure 3-2. Output from HelloServlet


3.4.2. POST, HEAD and Other Requests

As mentioned earlier, doGet( ) is just one of a collection of enabling methods for HTTP request types. doPost( ) is the corresponding method for POST requests . The POST request is designed for posting information to the server, although in practice it is also used for long parameterized requests and larger forms, to get around limitations on the length of URLs.

If your servlet is performing database updates, charging a credit card, or doing anything that takes an explicit client action, you should make sure this activity is happening in a doPost( ) method because POST requests aren't idempotent, which means that they aren't safely repeatable, and web browsers treat them specially. For example, a browser can't bookmark or, in some cases, reload a POST request. On the other hand, GET requests are idempotent, so they can safely be bookmarked, and a browser is free to issue the request repeatedly without necessarily consulting the user. You can see why you don't want to charge a credit card in a GET method!

To create a servlet that can handle POST requests, all you have to do is override the default doPost( ) method from HttpServlet and implement the necessary functionality in it. If necessary, your application can implement different code in doPost( ) and doGet( ). For instance, the doGet( ) method might display a postable data entry form that the doPost( ) method processes. doPost( ) can even call doGet( ) at the end to display the form again.

The less common HTTP request types, such as HEAD, PUT, TRACE, and DELETE, are handled by other doXXX( ) dispatch methods. A HEAD request returns HTTP headers only, PUT and DELETE allow clients to create and remove resources from the web server, and TRACE returns the request headers to the client. Since most servlet programmers don't need to worry about these requests, the HttpServlet class includes a default implementation of each corresponding doXXX( ) method that either informs the client that the request is unsupported or provides a minimal implementation. You can provide your own versions of these methods, but the details of implementing PUT or DELETE functionality go rather beyond our scope.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net