Request & ResponseS2C Home « Request & Response
In the previous two lessons we saw code examples of implementing the javax.servlet.Servlet
interface and extending the javax.servlet.GenericServlet
abstract class. Although it's
unlikely we will have a need to do this in the real world, it gave us an opportunity to use some of the methods of these types and also get a close look at the lifecycle of a servlet. What we haven't discussed
in any great detail yet are the request and response objects we have been using and how the service()
method always runs in its own thread. In this lesson we review these subjects in much greater detail.
In all the code examples seen so far we have used an override of the service()
method to place our HTML in. The arguments to the service()
method are the ServletRequest
and
ServletResponse
objects. These objects are created by the container, which provides implementations of the javax.servlet.ServletRequest
and javax.servlet.ServletResponse
interfaces. The ServletRequest
object provides methods for request data that includes parameter name and values, attributes, and an input stream that can be utilised by a servlet. The
ServletResponse
object provides methods that help in sending a response to a client from a servlet. Both of these objects are generic and protocol independent.
The vast majority of servlets work with the HTTP protocol and all our servlets from now on will be using HTTP. Because HTTP is the de facto protocol of choice there is a
complete package, javax.servlet.http,
devoted to HTTP specific servlets. We will take advantage of the servlet API by extending the javax.servlet.http.HttpServlet
abstract
class, which extends the GenericServlet
abstract class, with our own customized classes for the business processes required.
Closer inspection of the HttpServlet
class reveals that all methods have arguments for HttpServletRequest
and HttpServletResponse
objects apart from
public void service(ServletRequest req, Response resp)
. What happens is the public void service(ServletRequest req, Response resp)
of the HttpServlet
class overrides
the method from the GenericServlet
class and downcasts the ServletRequest
and ServletResponse
objects to HttpServletRequest
and HttpServletResponse
objects.
This method then dispatches client requests to the protected void service(HttpServletRequest req, HttpServletResponse resp)
method.
The protected void service(HttpServletRequest req, HttpServletResponse resp)
method delegates servicing to one of the HTTP doXXX()
methods, dependant upon the incoming HTTP
method passed with the client request. For this reason, when we extend the HttpServlet
class, there is rarely a need to override the service()
method as we have done in our previous
code examples. All our servlet needs to do is override the doXXX()
method with our business code to service the request from the client.
The diagram below illustrates the HTTP type hierarchy we have just discussed:
One Thread Per RequestTop
We mentioned in Java EE5 & Servlets - Using A Web Container, the benefits a web container gives us. One of the benefits was multithreading and how
the container creates a new java thread every time a servlet request is received. But how does this work in practice, what do we actually mean by a new thread for every request and what happens when a
client makes multiple requests? As far as the container is concerned every request is started in a new thread regardless of whether its from the same client source or divergent client sources. What this
means for our servlet classes is that every incoming request gets its own stack in which the service()
method gets invoked. After running the servlets service()
method, which
delegates processing to the appropriate doXXX()
method, the thread completes in a tidy manner.
The following slideshow shows three HTTP GET requests from three clients, that points to a servlet on the server that extends HttpServlet
and the steps involved through to the HTTP
response. Press the button below to step through the slideshow:
ServletRequest
OverviewTop
Whatever container you are using it must provide an implementation of the ServletRequest
interface and provide a ServletRequest
object. In this section we will tabularise some
of the methods of the ServletRequest
interface and describe what they do. There are a lot of methods in the ServletRequest
interface that we can split into functional groups
which cover client information, request body, request dispatching, request parameters, request protocol, request scoped attributes, resource information and transmission data.
The table below shows the declarations of some of the more common methods in the ServletRequest
interface, which we cover on the site, split into their respective functional groups:
Method Declaration | Description |
---|---|
Request Dispatching | |
RequestDispatcher getRequestDispatcher | Returns a RequestDispatcher object that operates as a wrapper for the resource located at specified path . |
Request Parameters | |
java.lang.String getParameter(java.lang.String name) | Returns the value of specified request parameter name as a String if the parameter exists, or null if not. |
java.util.Map getParameterMap() | Returns the parameters of this request as a java.util.Map . |
java.util.Enumeration getParameterNames() | Returns a java.util.Enumeration of String objects containing names of the request parameters for this request. |
java.lang.String[] getParameterValues | Returns the values of specified request parameter name as an array of String objects if the parameter exists, or null if not. |
Request Scoped Attributes | |
java.lang.Object getAttribute(java.lang.String name) | Returns the value of named attribute as type Object , or null if no attribute with specified name exists. |
java.util.Enumeration getAttributeNames() | Returns an Enumeration containing names of all the attributes available to this request. |
void removeAttribute(java.lang.String name) | Remove attribute with specified name from this request. |
void setAttribute | Store attribute with specified name in this request. |
Use the links in the table above to go to example code of the method in question. For more information on these and the other methods in the ServletRequest
interface follow the link to the official site at the end of the lesson.
ServletResponse
OverviewTop
The container must also provide an implementation of the ServletResponse
interface as well as creating a ServletResponse
object. In this section we will tabularise the methods
of the ServletResponse
interface and describe what they do. The methods in the ServletResponse
interface can be split into three functional groups which cover response protocol,
response streams and transmission data.
The table below shows the declarations of all the methods in the ServletResponse
interface, split into their respective functional groups:
Method Declaration | Description |
---|---|
Response Protocol & Transmission Data | |
java.lang.String getCharacterEncoding() | Returns the name of the character encoding (MIME charset) used for this client response. |
java.lang.String getContentType() | Returns the content type used for the MIME body sent in this response, or null if not specified. |
java.util.Locale getLocale() | Returns locale specified for this client response. |
void setCharacterEncoding(java.lang.String charset) | Sets character encoding (MIME charset) for client response. |
void setContentType(java.lang.String type) | Sets the content type of the client response, if the response has not been committed to be sent yet. |
void setLocale(java.util.Locale locale) | Sets specified locale of client response, if the response has not been committed to be sent yet. |
void setContentLength(int length) | Sets specified length of content body in client response. For HTTP servlets this is the HTTP Content-Length header. |
Response Streams | |
void flushBuffer() | Forces any content in the buffer to be written to the client and commits the response. |
int getBufferSize() | Returns actual buffer size used for the client response. |
ServletOutputStream getOutputStream() | Returns a ServletOutputStream object suitable for writing binary data in the client response. |
java.io.PrintWriter getWriter() | Returns a PrintWriter object suitable for sendint character text to the client response. |
boolean isCommitted() | Returns a boolean indicating if the client response has been committed. |
void reset() | Clears any data existing in the buffer as well as the status code and headers. |
void resetBuffer() | Clears any data existing in the buffer without clearing headers or status code. |
void setBufferSize(int size) | Sets preferred buffer size for the response body. |
Use the links in the table above to go to example code of the method in question. For more information on the methods in the ServletResponse
interface follow the link to the official site at the end of the lesson.
HttpServletRequest
OverviewTop
When using HTTP we extend the ServletRequest
interface with the HttpServletRequest
interface so we can create HTTP servlets. Whatever container you are using it must provide
an implementation of the HttpServletRequest
interface and provide a HttpServletRequest
object. In this section we tabularise some methods of the HttpServletRequest
interface and describe what they do.
There are a lot of methods in the HttpServletRequest
and all apply specifically to the HTTP protocol, whereas the methods in the ServletRequest
interface are more generic and can be
used with any protocol. We can split the HttpServletRequest
methods into functional groups which cover request headers, request protocol data, request path, security related and session management.
The table below shows the declarations of some of the more common methods in the HttpServletRequest
interface, which we cover on the site, split into their respective functional groups:
Method Declaration | Description |
---|---|
Request Headers | |
java.lang.String getHeader(java.lang.String name) | Returns a String object containing the value of the specified name request header. |
java.util.Enumeration getHeaderNames() | Returns an Enumeration of String objects of all header names this request contains. |
java.util.Enumeration getHeaders | Returns an Enumeration of String objects of all values for the specified name request header. |
Request Protocol Data | |
java.lang.String getMethod() | Returns name of HTTP method this request started from. |
Request Path | |
java.lang.String getQueryString() | Returns query string that is contained in the request URL after the path, or null if none present. |
java.lang.String getRequestURI() | Returns complete request URL from the protocol name up to, but excluding, the query string. |
Security Related | |
Cookie[] getCookies() | Returns an array of all javax.servlet.http.Cookie objects the client sent with this request. |
Session Management | |
HttpSession getSession() | Returns current HttpSession associated with this request. If no current session exists will return a new session. |
HttpSession getSession(boolean create) | Returns current HttpSession associated with this request. If no current session and create is set to true will return a new session, otherwise null . |
Use the links in the table above to go to example code of the method in question. For more information on these and the other methods in the HttpServletRequest
interface follow the link to the official site at the end of the lesson.
HttpServletResponse
OverviewTop
Whatever container you are using it must provide an implementation of the HttpServletResponse
interface and provide a HttpServletResponse
object. In this section we will tabularise the methods
of the HttpServletResponse
interface and describe what they do. The methods in the HttpServletResponse
can be split into four functional groups which cover cookies, HTTP status
codes and redirection, response headers and URL rewriting.
The table below shows the declarations of all the non-deprecated methods in the HttpServletResponse
interface split into their respective functional groups:
Method Declaration | Description |
---|---|
Cookies | |
void addCookie(Cookie cookie) | Adds specified cookie to the client response. |
HTTP Status Codes and Redirection | |
void sendError(int sc) | Clears the buffer and sends the client an error response using the specified sc status code. |
void sendError(int sc, java.lang.String msg) | Sends the client an error response using the specified sc status code and msg message. |
void sendRedirect(java.lang.String location) | Sends the client a temporary redirect response using the specified location redirect location URL. |
void setStatus(int sc) | Sets the status code for this client response. |
Response Headers | |
void addDateHeader(java.lang.String name, long date) | Adds a response header with specified name and date . |
void addHeader | Adds a response header with specified name and value . |
void addIntHeader(java.lang.String name, int value) | Adds a response header with specified name and int . |
boolean containsHeader(java.lang.String name) | Returns a boolean dependendant upon specifed name response header having been already set. |
void setDateHeader(java.lang.String name, long date) | Sets a response header with specified name and date . |
void setHeader | Sets a response header with specified name and value . |
void setIntHeader(java.lang.String name, int value) | Sets response header with specified name and value . |
URL Rewriting | |
java.lang.String | Encodes specified url for use in the sendRedirect() method if encoding is needed or returns the URL unchanged. |
java.lang.String encodeURL(java.lang.String url) | Encodes specified url by including the session ID in it if encoding is needed or returns the URL unchanged. |
Use the links in the table above to go to example code of the method in question. For more information on the methods in the HttpServletResponse
interface follow the link to the official site at the end of the lesson.
Extending HttpServlet
Top
Extending the HttpServlet
class has several advantages over extending the GenericServlet
class when you are working with the HTTP protocol. As mentioned above the
public void service(ServletRequest req, Response resp)
of the HttpServlet
class overrides the method from the GenericServlet
class and downcasts the
ServletRequest
and ServletResponse
objects to HttpServletRequest
and HttpServletResponse
objects. This method dispatches requests to the
protected void service(HttpServletRequest req, HttpServletResponse resp)
method which then delegates servicing to one of the HTTP doXXX()
methods, dependant upon the incoming
HTTP method passed with the client request.
In almost all cases you will override either the doGet()
or doPost()
method or both of them; the doGet()
method being the default. The following code example is our
first look at extending the HttpServlet
class with our own custom HTTP servlet.
Coding The DDTop
Within the _ServletsJSP
folder create a new folder for the web application we will create in this lesson and call it sayings
Within the sayings
folder create separate folders to hold our DD, source files and our compiled byte code and called dd
, src
and classes
. Within the
src
folder create a subfolder called controller
.
So after creating these folders your directory structure should look something like the following screenshot:
There are no DD entries for this application that we haven't seen already.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>OldSayings</servlet-name>
<servlet-class>controller.HttpServletDemoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OldSayings</servlet-name>
<url-pattern>/sayings</url-pattern>
</servlet-mapping>
</web-app>
Save the web.xml
file in the DD
folder.
Coding The ServletTop
We are now ready to code up a servlet that extends the javax.servlet.http.HttpServlet
class, so cut and paste the following code into your text editor and save it in the c:\_ServletsJSP\sayings\src\controller directory.
package controller;
// I/O Imports
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HttpServletDemoServlet extends HttpServlet {
private static final long serialVersionUID = 871964L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Create a table of sayings as a response
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.print("<html><head></head>" +
"<body><h1>Sayings</h1><table border=\"2\">" +
"<tr><td>A stitch in time saves nine.</td>" +
"<td>To many cooks spoil the broth.</td></tr>" +
"<tr><td>The early bird catches the worm.</td>" +
"<td>Blood is thicker than water.</td></tr>" +
"</table></body></html>");
}
}
The difference with this servlet from previous examples is that we overriding one of the doXXX()
methods instead of the service()
method as we have done in all previous examples.
The other dissimilarities are the request and response objects are now HTTP specific and we now extend HttpServlet
; apart from this the servlet is very similar to those seen before.
Compiling The ServletTop
Open your command line editor:
Change to directory c:\_ServletsJSP\sayings\src\controller
Compile HttpServletDemoServlet.java
using the java compiler with the -cp
and -d
options as below, making sure you change apache-tomcat-6.0.37
to wherever you downloaded Tomcat to.
javac -cp c:\apache-tomcat-6.0.37\lib\servlet-api.jar -d ..\..\classes HttpServletDemoServlet.java
The following screenshot shows that we get a clean compile and also the HttpServletDemoServlet
class now compiled into the classes\controller
directory.
Tomcat DeploymentTop
Go to your Tomcat installation which in my case is:
C:\apache-tomcat-6.0.37\webapps\
Within the webapps
folder create a folder for our web application called sayings
Within the sayings
folder create the WEB-INF
folder.
Copy the web.xml
file and the classes
directory and contents from our development environment into the WEB-INF
folder.
After creating these folders and copying the files from development your Tomcat directory structure within the webapps\sayings
folder should look something like the following screenshot:
Testing Our ServletTop
Open a command prompt and change the directory to the location of our Tomcat bin directory and then type in startup
(Windows 7) or startup.sh
(Linux/Unix/OSX).
Press Enter and the Tomcat server should open up in a new window.
You can also start up Tomcat by double-clicking the startup
batch file within your Tomcat /bin
folder.
With Tomcat up and running type the following into your web browser address bar and press enter:
http://localhost:8080/sayings/sayings
The web browser should be directed to the HttpServletDemoServlet
servlet class within Tomcat, execute and produce a screen that looks like the following:
As you can see the response from the doGet()
method has returned our sayings in a table.
Java DocumentationTop
The following link will take you to the online version of documentation for the Servlet API Documentation . Take a look at the documentation for the interfaces we have discussed, which you can find by scrolling down the lower left pane and clicking on a package and then the interface.
Lesson 8 Complete
In this lesson we took a closer look at requests and responses and how a new thread is aloocated each time a request is received from the client.
What's Next?
That's the end of the the Servlet 2.5 Basics section. We start the intermediate lessons by taking a look at HTML forms and how we work with them.