Chapter 2 explores various ways to implement and publish RESTful services in Java, which has a rich set of built-in and third-party APIs. The current chapter introduces a tried-and-true way to do RESTful services in Java: the service is implemented as a JSP script, which a web server such as Tomcat or Jetty translates into a servlet, and the servlet then is published with the web server.
An HttpServlet
is a natural, convenient way to implement RESTful web services for two
main reasons. First, such servlets are close to the HTTP metal. For example,
the HttpServlet
class has methods such as doGet
, doPost
, doPut
, and
doDelete
that match up with the HTTP verbs aligned with the CRUD operations. These
servlet methods execute as callbacks that the servlet container, explained shortly, invokes
as needed. The HttpServlet
class also provides symbolic constants for HTTP status codes, for
example, SC_NOT_FOUND
for status code 404 and SC_METHOD_NOT_ALLOWED
for status
code 405. Each HttpServlet
do-method has the same two arguments:
an HttpServletRequest
and an HttpServletResponse
. The servlet request contains, as
key/value pairs, all of the appropriate information encapsulated in the HTTP request,
regardless of the request verb—for a GET request, the HttpServletRequest
would include
any key/value pairs in a query string; for a POST request, this data structure would
include any key/value pairs in the POST request body.
The HttpServletRequest
map is easy to read and, if needed, easy to update and forward.
The HttpServletResponse
has methods to adjust the HTTP response message as needed,
and this class encapsulates an output stream to communicate back to the
client.
A second major advantage of servlets is that they execute in a servlet container, which is middleware that mediates between the application code of the servlet and the web server that provides the usual types of support: wire-level security in the form of HTTPS transport, user authentication and authorization, logging and troubleshooting support, server configuration, local or remote database access, naming services, application deployment and administration, and so on. In the Tomcat web server, the servlet container is named Catalina. Because the servlet container is such an integral part of a Java-based web server, it is common to conflate the container name (Catalina) and the server name (Tomcat), a practice followed here. (In Jetty, the server and the container have the same name: Jetty.) In any case, a Java-centric web server such as Tomcat is the natural way to publish real-world web services, including RESTful ones, written in Java. A servlet container typically houses several instances of executing servlets, each awaiting client requests (see Figure 1-7).
Here is a short, more technical review of servlets with emphasis on their use to
deliver RESTful services. The class HttpServlet
extends
the class GenericServlet
, which in turn implements the
Servlet
interface. All three types are in a
package that is not included in core Java. (Tomcat and Jetty provide
a JAR file servlet-api.jar that contains the required package.) The
Servlet
interface declares five methods, the most
important of which is the service
method that a web
container invokes on every request to a servlet. The
service
method has a ServletRequest
and a ServletResponse
parameter. The request
is a map that contains the request information from a client, and the response
provides a stream to send responses back to the client. The
GenericServlet
class implements the Servlet
methods in a transport-neutral fashion, whereas
the HttpServlet
subclass of GenericServlet
implements these methods in an
HTTP-specific way. Accordingly, the service
parameters in the
HttpServlet
have the types HttpServletRequest
and
HttpServletResponse
. The HttpServlet
also provides request filtering that naturally
supports a REST-style service: in an HttpServlet
, the overridden service
method dispatches a incoming
GET request to the method doGet
, an incoming POST
request to the method doPost
, and so on. Because HTTP is the dominant transport for websites and
web services, the HttpServlet
is an excellent choice for implementing either.
In the HttpServlet
class, the do-methods such as doGet
and doPost
are defined as no-ops, (methods with empty
bodies); these methods can be overridden as needed in a programmer-derived subclass.
For example, if the class MyServlet
extends HttpServlet
and overrides doGet
but
not doPost
, then doPost
remains a no-op in MyServlet
instances. A servlet programmer
overrides the do-methods of interest and ignores the rest.
Servlets are written in Java and, therefore, have access to all of the Java libraries, standard and contributed.
JSP scripts, by contrast, are an arbitrary mix of HTML and code. In the case of websites, JSP scripts typically serve
as HTML templates and, under best practices, the major code segments involve references to backend JavaBeans.
In the case of web services, by contrast,
JSP scripts would consist predominantly or even exclusively of code because service clients do not expect
HTML payloads as responses.
The advantage of a JSP script over an HttpServlet
is that the programmer does not need to
compile a JSP script. The Java-aware web server assumes this responsibility.
A JSP script is deployed as a text file but executes as a servlet because the web server automatically
translates the script into an HttpServlet
before loading one or more instances of the
resulting servlet into the servlet container. For short examples and for the kind of experimentation
typical of code development, JSP scripts are attractive. For deployment to production, the
Java code of a servlet would be best practice. Some of the shorter servlet-based examples in this book use JSP scripts,
but most of the examples use classes that explicitly extend HttpServlet
.
Get Java Web Services: Up and Running, 2nd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.