- Objectives
- Introduction
- Overriding HttpServlet GET, POST, and PUT Methods
- Triggering HttpServlet GET, POST, and PUT Methods
- Interfacing with HTML Requests
- Web Application Scope
- Servlet Life-cycle
- Using a RequestDispatcher
- Web Application Context
- Context Within a Distributable Web Application
- Chapter Summary
- Apply Your Knowledge
Overriding HttpServlet GET, POST, and PUT Methods
1.1 For each of the HTTP methods, GET, POST, and PUT, identify the corresponding method in the HttpServlet class.
GET
POST
PUT
This exam objective addresses the most-used feature of servlets, namely, responding to HTTP requests. The exam will have several questions on this topic. These three types of requests dominate browser-server traffic.
The following code is a minimal template showing you how to use the GET, POST, and PUT methods. GET appends data to the URL before the URL is submitted to the server, whereas POST sends the data to the server separately from the URL. GET submissions can only be 1KB in length in most cases, whereas POST submissions can be arbitrarily large. The results of a GET submission can be reliably bookmarked, whereas the results of a POST submission can't. There are several differences between them which are explained later in this section.
These methods are called by the service method (not required in your servlet as it is in HttpServlet, as this method is inherited from HttpServlet). Together they can look like Listing 4.3.
Listing 4.4 Servlet That Handles GET, POST, and PUT Requests
/* doGetdoPostdoPutServlet.java, v 1.0 * SCWCD Exam Objective 1.1 = doGet(), doPost(), doPut() * */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** * A servlet that reports back to the browser * the type of request received. * * @author Reader@Que */ public class doGetdoPostdoPutServlet extends HttpServlet { // doGet() - SCWCD Exam Objective 1.1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { reportType("doGet", response); } // doPost() - SCWCD Exam Objective 1.1 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { reportType("doPost", response); } // doPut() - SCWCD Exam Objective 1.1 public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { reportType("doPut", response); } public void reportType(String requestType, HttpServletResponse response) throws IOException, ServletException { // set the MIME type response.setContentType("text/html"); // use this to print to browser PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>doGetdoPostdoPutServlet" + "</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Your Request</h1>"); out.println("Your request type: " + requestType); out.println("</body>"); out.println("</html>"); } }
Listing 4.3 sends a basic HTML message back to the browser that looks like Figure 4.3.
Figure 4.3 Filtering request types using a servlet.
It is the service method that calls the doXXX() methods. While you normally wouldn't override the service method, Listing 4.4 presents a skeleton example of what you could do with it. You might want to preprocess the request before sending it on to the appropriate doXXX() method.
Listing 4.4 Service Method Example
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { doGet(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else { // Servlet doesn't currently support // other types of request. String errMsg = "Method Not Supported"); resp.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } }
GET
The GET type request is normally used for simple HTML page requests. It has this syntax:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { //your code here}
When you write a servlet, this is the one method that you will start with. If this method is all you had in your servlet, it would handle the majority of your Web server's needs regarding this servlet. Notice, that the init() and service() methods involved in a request are already provided by the HttpServlet class, so they don't need to be overridden, although you can do so.
The GET is the most common type of browser request. According to the Hypertext Transfer Protocol standard, the GET method means "retrieve whatever information (in the form of an entity) is identified by the Request-URI." For a full discussion on naming and addressing (URL vs. URI) please see http://www.w3.org/Addressing/. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process." In our example, the test message is the entity.
GET Method
The GET is the most common type of browser request. The GET request is defined by the Internet Society's RFC 2616: Hypertext Transfer ProtocolHTTP/1.1. See section 9.3 of RFC 2616 at ftp://ftp.isi.edu/in-notes/rfc2616.txt.
This method is where your servlet does most of its labor. You could process a simple HTML response or hit a database with a query.
Table 4.1 provides a list of differences between GET and POST requests.
Table 4.1 GET vs. POST Request
GET |
POST |
Query string or form data is simply appended to the URL as name-value pairs. |
Form name-value pairs are sent in the body of the request, not in the URL itself. |
Query length is limited (~1KB). |
Query length is unlimited. |
Users can see data in address bar. |
Data hidden from users. |
http://mycompany.com/support? |
http://mycompany.com/support |
doGet(). |
doPost(). |
For getting (retrieving) data only. |
For causing a change on the server (store data in DB). |
ASCII. |
ASCII + Binary. |
Easy to bookmark. |
Hard to bookmark. |
Used more. |
Used less. |
The following short listings exemplify the GET and POST requests
<html> <body> <form method="GET" action="/myservlet/process"> <input type="text" name="product" size="25" maxlength="35" value="type product name here"> <input type="submit" name="submitButton" value="Submit"> </form> </body> </html> <html> <body> <form method="post" action="/myservlet/process"> <input type="text" name="product" size="25" maxlength="35" value="type product name here"> <input type="submit" name="submitButton" value="Submit"> </form> </body> </html>
POST
The POST type request is most often used by HTML forms. It has this syntax:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { //your code here}
The POST method is more sophisticated than a GET request. Normally, a Web form has fields whose names and values are sent to the server in key-value pairs. The POST is designed for posting long messages (for example, to a bulletin board, newsgroup, mailing list); providing a block of data, such as the result of submitting a form; and submitting long data fields to a database (such as a SQL insert of lengthy string). Sometimes the action performed by the POST method doesn't return a standard HTML page. Suppose you updated a database table. The database doesn't send back an HTML confirmation on its own. You would have to wrap the database results in HTML manually. You also have the option of sending back an empty response with a header status of either 200 (OK) or 204 (No Content). A No Content status tells the browser that it shouldn't expect any HTML. You might want to do this if it is software to software interaction and no eyeballs are waiting to see a Web page.
POST Method
The POST is the most sophisticated of the methods covered by this part of the exam. The POST request is defined by the Internet Society's RFC 2616: Hypertext Transfer ProtocolHTTP/1.1. See section 9.5 of RFC 2616 at ftp://ftp.isi.edu/in-notes/rfc2616.txt.
Normally, this method is used to process a form submitted by a browser. You will very likely be looking for form field names and values. For example, the following snippet is how you would grab the value of the field formCountField that the user supplied a value for:
//read the query string int customerRequest = 0; String count = request.getParameter("formCountField"); try { customerRequest = Integer.parseInt(count); } catch (Exception e) { // NumberFormat or NullPointerException processError(e); }
PUT
The PUT type request is a means of uploading files to the server. While uploading is its original intent, I have not seen it used much. Instead, POST is generally used to upload files. The PUT handler has this syntax:
public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { //your code here}
The doPut() method is called by the server (via the service method) to handle a PUT request. Uploading files from a browser has always been difficult. The idea behind the PUT operation is to make uploading straightforward. It is supposed to allow a client to place a file on the server, just like sending a file by FTP. The javadoc for this method warns that when overriding this method, you should leave intact any content headers sent with the request (including Content-Length, Content-Type, Content-Transfer-Encoding, Content-Encoding, Content-Base, Content-Language, Content-Location, Content-MD5, and Content-Range). This method is rarely used, but it is powerful if you need it.
Listing 4.5 is a simplified HTML page that creates a file upload page that will direct the file contents to a servlet.
Listing 4.5 HTML Form Example
<html> <body> <form enctype="multipart/form-data" method="PUT" action="localhost:8080/examples/servlet/UploadServlet"> <input type="file" size="20" name="FileToUpload" value="Select File"> <input type="submit" name="UploadFile" value="Upload"> <input type="reset" value="Reset"> </form> </body> </html>
Listing 4.6 is a servlet that can accept an uploaded file.
Listing 4.6 Servlet That Handles a File Upload from the Client
import java.io.*; import java.util.*; import java.net.*; import javax.servlet.*; import javax.servlet.http.*; public class UploadServlet extends HttpServlet { static final String dir="C:/temp"; public void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter outHTML = res.getWriter(); outHTML.println("done"); try { int i; InputStream input; input = req.getInputStream(); BufferedInputStream in = new BufferedInputStream(input); BufferedReader reader = new BufferedReader( new InputStreamReader(in)); File outputFile = new File("c:/temp/out.txt"); FileWriter out = new FileWriter(outputFile); while ((i = reader.read()) != -1) { out.write(i); } out.close(); in.close(); } catch (IOException e) {} } }
You need to account for the header and footer lines that the stream attaches to the actual file contents. The stream looks like this:
------------BB1rHqKAOHkiUoiFS3VI6v Content-Disposition: form-data; name="FileToUpload"; filename="Candle.txt" Content-Type: application/octet-stream; name="Candle. txt" // ... //actual file content here // ... ------------BB1rHqKAOHkiUoiFS3VI6v Content-Disposition: form-data; name="UploadFile" Upload ------------BB1rHqKAOHkiUoiFS3VI6v
Therefore, you will need to search (indexOf) for the start of the actual file content by looking for the Content-Type and subsequent name parameters like so:
int headerEnd = line.indexOf("Content-Type: "); headerEnd = line.indexOf("name=\"", headerEnd); headerEnd = line.indexOf("\"", headerEnd + 7); //last quote
Likewise, you need to search the end of the file for the telltale Content-Disposition and preceding "------------" marker like so:
int footerStart = line.lastIndexOf ("Content- Disposition: "); footerStart = line.lastIndexOf ("---------", footerStart);
Lastly, you will grab the text between the two like so:
fileContent = line.substring(headerEnd, footerStart);
You can refer to RFC 1867 to learn more about uploading files through an HTML form (http://www.servlets.com/rfcs/rfc1867.html). This is all tedious, so you might just grab an open source (http://www.servlets.com/cos/index.html) or commercial Bean that uploads files such as uploadBean (http://www.javazoom.net/jzservlets/uploadbean/uploadbean.html) or jspSmartUpload (http://www.jspsmart.com/).
Listing 4.6 worked when placed in the doPost() method (and the form method of Listing 4.5 is set to post), but did not work in the doPut() method using IE or Opera against Tomcat (version 4). I verified that the doPut() method is called as expected in the servlet. However, even after much tweaking, this file upload code failed when placed in the doPut method as shown previously. If you only change doPut to doPost it works?! Although I need to research this problem with Tomcat, you do need to understand that PUT is used to upload files to a Web server and that this is usually done by non-browser, client-side Web content development tools.