When I started using the Java servlet back in 2000, I read about the HttpServlet methods that correspond to the significant HTTP methods, but I didn't really override any methods in the majority of my servlets other than doGet and doPost. Looking back on the early servlet-focused books and articles, it is not surprising that this was the case because these materials focused on those two methods as well.
Although the Javadoc-based API information for Java EE 5 briefly discusses alternative methods in
HttpServlet
that can be overridden, many tutorials available even today focus on doGet
and doPost
. For example, the highly useful Java Servlet API Tutorial has an HTTP Support section that mentions the other methods but focuses on doGet
, doPost
, doHead
. Similarly, the Java EE 5 Tutorial (PDF) also focuses on use of the HttpServlet
's doGet
method.Roy Fielding's REST dissertation has been a significant catalyst in motivating many of us to think about HTTP differently. Specifically, we are now more inclined to think about the other methods supplied with HTTP. While many tools and browsers do not provide great support for all the major HTTP methods, the Java servlet has provided this support for some time and is an excellent mechanism for implementing and simulating operations that take advantage of the major HTTP methods.
It is very easy to take advantage of
HttpServlet
's support for major HTTP methods. This is demonstrated in the next code sample for the Java servlet class SimpleHttpServer.java
:SimpleHttpServer.java
package dustin.flex.rest;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Simplistic Java EE server-side application intended for demonstration of
* HTTP methods often use in REST-based applications.
*
* @author Dustin
*/
public class SimpleHttpServer extends HttpServlet
{
/**
* Servlet method responding to HTTP GET methods calls.
*
* @param request HTTP request.
* @param response HTTP response.
*/
@Override
public void doGet( HttpServletRequest request,
HttpServletResponse response ) throws IOException
{
final PrintWriter out = response.getWriter();
out.write("GET method (retrieving data) was invoked!");
}
/**
* Servlet method responding to HTTP POST methods calls.
*
* @param request HTTP request.
* @param response HTTP response.
*/
@Override
public void doPost( HttpServletRequest request,
HttpServletResponse response ) throws IOException
{
final PrintWriter out = response.getWriter();
out.write("POST method (changing data) was invoked!");
}
/**
* Servlet method responding to HTTP PUT methods calls.
*
* @param request HTTP request.
* @param response HTTP response.
*/
@Override
public void doPut( HttpServletRequest request,
HttpServletResponse response ) throws IOException
{
final PrintWriter out = response.getWriter();
out.write("PUT method (inserting data) was invoked!");
}
/**
* Servlet method responding to HTTP DELETE methods calls.
*
* @param request HTTP request.
* @param response HTTP response.
*/
@Override
public void doDelete( HttpServletRequest request,
HttpServletResponse response ) throws IOException
{
final PrintWriter out = response.getWriter();
out.write("DELETE method (removing data) was invoked!");
}
@Override
public String getServletInfo()
{
return "Server-side application demonstrating HTTP methods.";
}
}
This class can be referenced in the Java EE web descriptor file (
web.xml
) as shown next.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
<display-name>Simple Servlet Example Demonstrating Http Method Support</display-name>
<description>Demonstrates HttpServlet Support of HTTP Methods</description>
<servlet>
<servlet-name>SimpleHttpServer</servlet-name>
<servlet-class>dustin.flex.rest.SimpleHttpServer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SimpleHttpServer</servlet-name>
<url-pattern>/httpServer</url-pattern>
</servlet-mapping>
</web-app>
If we build the servlet shown above and assemble it with the
web.xml
file shown above into a WAR file that is deployed to a Java EE web server, we can then have clients contact the simple servlet via one of the four HTTP methods GET, POST, PUT, and DELETE (assuming the client is capable of using these different HTTP methods). In fact, we'll also see later in this blog post that even the HTTP methods TRACE, OPTIONS, and HEAD are supported by the HttpServlet. I did not override them in my servlet above because the default implementations of these methods (doTrace, doOptions, and doHead) typically work well for what we need.For the example in this blog posting, I am deploying the assembled WAR with the servlet and
web.xml
file shown above to GlassFish (though any Java EE web/application server will work) using a context of restful. Coupled with the path defined in the web descriptor file and using the default port on GlassFish, my overall URL for accessing my servlet is http://localhost:8080/restful/httpServer. When I place this URL in my web browser, the results appear as shown in the figures below for Firefox and for Google Chrome.Note that in both cases, the default method used for the browser communication with the servlet was HTTP GET. I will now begin using RESTClient to easily communicate with this servlet with alternative HTTP methods. This tool is provided as an executable JAR and is easily used, but additional instructions on using it are available here and here.
Because the browsers automatically demonstrated use of a client using HTTP GET to communicate with the server, I will begin showing RESTClient examples with GET as well. The following two screen snapshots demonstrate RESTClient showing the headers and then the body of the response. The HTTP response information is shown at the bottom of the UI.
HTTP GET Response Headers
HTTP GET Response Body
The two screen snapshots above use RESTClient to show the headers and body of the HTTP GET response. For POST, PUT, and DELETE, I will only show the bodies.
HTTP POST Response Body
HTTP PUT Response Body
HTTP DELETE Response Body
The response body for the TRACE method is shown next.
HTTP TRACE Response Body
The HTTP HEAD method works like the GET, but intentionally does not include a body. Similarly, the most interesting portion of the response for OPTIONS is also in the header. Because the HEAD's body is empty and the header looks like that for GET, I don't show it here. For OPTIONS, I show the headers rather than the bodies of those responses next. Note that the options provided by the server are shown in the "Allow" header field of this response.
HTTP OPTIONS Response Headers
As the "Allow" header field in the OPTIONS response indicates, the server supports the HTTP methods GET, HEAD, POST, PUT, DELETE, TRACE, and OPTIONS.
Conclusion
Although Java servlets are more than a decade old, they remain a powerful and highly useful technology. While they may not be as trendy as younger and more currently hip technologies, this blog posting serves as a reminder of how relatively easy it is to apply their rich features to modern-day development. Servlets have supported the major HTTP methods for many years and because of the
HttpServlet
's close association with HTTP, it is not surprising that the HttpServlet
was ready for action when REST became a widely popular topic.
2 comments:
How to run command line version to PUT xml???
With the end of Google Code hosting projects, rest-client is now hosted on GitHub.
Post a Comment