19 HTTP specific API for Servlets
Pravin Jain
Introduction
Welcome to this module on HTTP specific APIs on Servlets. In the earlier module we have seen the general part of API. So far, we have explored the javax.servlet package.
Now we are looking at the javax.servlet.http package. As far as the servlet specification is concerned, what it says is, any request-response based protocol is supported by the implementation of servlet specification…But one thing which is mandatory is, Whatever is your servlet container, it must implement and support the HTTP protocol. There as a part of servlet specification itself, we have a package called javax.servlet.http which is talking about specifics of HTTP protocol.
Here we have to recollect what we have learnt in HTTP protocol, the various parts of HTTP protocol. From the generic API we have seen the interfaces like ServletRequest, the ServletResponse which were very general. There was nothing specific about HTTP protocol there. But when we talk of javax.servlet.http package, it has additional interfaces. It has an interfaces called
a) HTTPServletRequest
b) HTTPServletResponse.
These are the interfaces which are extending from generic interfaces. The general interfaces were ServletRequest and ServletResponse. Those are being extended to have an API which is specific to HTTP protocol.
What exactly happens is whenever the request arrives, since the request which comes is an HTTP request, the container is creating objects which are implementations of HTTPServletRequest and HTTPServletResponse.
These are extending the ServletRequest and ServletResponse interfaces. which are from the javax.servlet package.
So in this module, we will cover these 2 interfaces called HTTPServletRequest and HTTPServletResponse
We also have another class here called HTTPServlet which is nothing but extending from GenericServlet class. So what are all those things which are part of HTTPServletRequest, HTTPServletResponse
What is additional there? and things related to class called HTTPServlet.
HttpServletRequest
Let us begin by understanding what is additional in the HTTPServletRequest? ServletRequest was very general. It just says, oh you could have any parameters. It says you could have content. When it comes to Http, of course HTTP also has that. HTTP can have parameters.
How do we have parameters using HTTP? There are 2 ways:
One way is, as part of URL itself. Someone could put those query string, using a ‘?’ and then parameter_name=value [& (parameter_name=value)] and so on. You could have any number of parameters being specified as part of URL itself. If that is the case the parameter is going to be available in the ServletRequest itself.
Another way is, when someone submits a form. In the HTML form, we are able to specify method=post or method=get What happens when someone says method=get? The parameters which are coming from inputs tags become part of URL If the method was specified as POST, the parameters will going as a part of the content rather than going as part of URL. A string similar to the query string becomes the content of the HTTPRequest.
Let us look at the structure of HTTPRequest. The first ine is typically
GET resource_or_path protocol_version
In the interface called HTTPServletRequest, we have additional methods for these. You might be interested in knowing what is the HTTP method? Whether it is GET or POST or PUT or DELETE etc? we have various HTTP methods. In HttpServletRequest interface, we have a method called getMethod() which returns a String. This is method from
HTTPServletRequest.
You are interested in the resource!!! You have a method called getRequestedURL() which would give us the whole URL as a StringBuffer object. It is a StringBuffer which means it is modifiable. It can be modified before it is getting forwarded to a RequestDispatcher., by modifying it, there could be some parameters that could be added, yes, that could be done.
We even have methods to get various parts of URL, This URL from the servlet specification point of view, is
Application name as the first part of URL
/application_name/…
so you are interested in knowing the application name…? We have this method in HTTPServletRequest, called getContextPath().
public String getContextPath()
that gives us the part which is related to the application, Then we have a method which will be specifying., what part of the URL is identifying the Servlet?
There is URL-pattern which is mapped to a Servlet,.So which part of the URL matched the pattern? because of which this invocation has taken place.
For that we have a method called getServletPath()
public String getServletPath()
So you can know the ServletPath which is responsible for the identification of the Servlet. and then after the servlet path, for e.g. you have that wildcard /* at the end.
So whatever is there after /*, if there is something in current URL which matches to it, that could also be identified separately by method called by getPathInfo()..
public String getPathInfo()
So from HTTPServletRequest, we not only get the parameters, we get the method name, we get various parts of URL, we can get the whole URL as a StringBuffer also. We also have a method called getQueryString()
public String getQueryString()
to know what is there in the Query String of the URL.
we also have a method called getProtocol(), .
public String getProtocol()
to know, what’s the protocol. We have that third part saying that this request is for HTTP/1.1 or 1.0, for secured URL you might have used HTTPS, you can even know that also by using a method called getScheme()
public String getScheme()
which will identify the protocol http or https, what is being followed here in the URL string? You even have a method for knowing that the protocol is secure or not.
the method is isSecure().
public boolean isSecure()
For https isSecure() is true. if we go further in the HTTP Request, what do we have?
after the 1st line of the request, we have the headers. You might be interested in knowing what all headers have come and their values. we have methods for fetching the values of headers from the request that has arrived? we have methods like getHeaderNames()
public Enumeration<String> getHeaderNames()
which returns the Enumeration of String. getHeaders()
public String[] getHeaders(String headerName)
which takes the Header name because same header may have multiple values, it returns an array of Strings or you may use getHeader() with only the name..
public String getHeader(String headerName)
which gives the first value of header if the same header is repeated multiple times. We have header-specific methods also. for e.g. there is a header for content-type. So you might use the method called getContentType().
public String getContentType()
or use the method called getHeader() where you pass “content-type” as a parameter. For some popular header names we might have some readymade methods. Instead of using the method called getHeader(),we might use methods for some of the commonly used headers.
Talking about headers, in HTTPServletRequest we have a method called getHeader() which takes a String and gives a string. For example, for content-length we know that the integer will be retuned. So instead of using getHeader() and then using the parseInt() method for getting the string converted to int, or for that matter, any header that we understand is going to be an integer type, instead of using a parseInt() separately, you have convenient methods. so wherever you know, this header has an integer value, you could be using the method called getIntHeader().
public int getIntHeader(String headerName)
It is same as getHeader() but also doing conversion into int. There are date-time headers like last-modified, there are headers which are nothing but representative of date and time.if- modified-since is another one. if-modified-since is useful when there is caching being done. So if we have headers which are involving date and time. the HTTP protocol says, there are 3 different format of the dates which are supported. when the request comes, for the specific header which has a date information, you would be having different formats. so here if you use getHeader() method and then try to parse, you will have to try all the 3 formats. you will have to identify which format does it follows. Instead of that there is a convenient method called getDateHeader(),
public long getDateHeader(String headername)
here you pass a header name, it returns long (time in milliseconds) a standard thing in JAVA.
We have this method called getCookies() to return an array of Cookie which we will be looking at in a later module. We might have methods for authentication specifying what kind of authentication was carried out? which is getAuthType().
public String getAuthType()
We have methods to know if the authentication has been carried out. who is the current user from where the request has come. We also have methods like getRemoteUser().
public String getRemoteUser()
or getUserPrincipal()
public java.security.Princiapl getUserPrincipal()
which returns an object of Principal which belongs to java.security package. Principal in turn has a method called getName()
public String getName()
which returns the name of the user.
HttpServletResponse
Now let’s have a look at the methods of HTTPServletResponse. if we look at the structure of the an Http response, A Http response as discussed in an earlier module, has first line as: protocol-version response_code message eg.
HTTP/1.1 200 OK
HTTPServletResponse has a method called getStatus()
public int getStatus()
which gives us the status code determining what is the response. There is a method called setStatus()
public void setStatus(int status)
to set the status that is to be sent as a part of response. As it is server side, we are actually setting up the response. As part of setting up the response, we can also set up the response status also. to send a specific response to the client, we have a method called sendError().(don’t go by the name)
public void sendError(int status)
sendError() takes integer status code and the string for the message.
public void sendError(int status, String message)
it would not be an error, you might be giving a successful status code here and a message. When we use the sendError() method, the container has its own specific template according to which it will send the content. As far as the status code is concerned, it is this code which we use in this sendError() method. So sendError() doesn’t necessarily mean that there is an error response.
Now coming to the headers. Some default values will be there for some common headers decided by the container. If you want to send some headers which are not normally sent. we have a method called setHeader().We might have to send a header when we do redirection, for that we have convenience method called sendRedirect()
public void sendRedirect(String location)
where you specify the new location as URL string. You don’t have to set up a header for the location. The appropriate status code and the appropriate location header and the other content would then be sent by the container for us. We don’t have to setup anything else. We just call sendRedirect(). Many times when we want to say sendRedirect(),we are passing a URL, we want to have some escaping done for us. Sometimes session information need to be included as a part of URL itself. we have a method in HTTPServletResponse called encodeURL().
public String encodeURL(String url)
This could be used for encoding the URL by removing the escape sequences for us, and including session information in the url.
We have got methods for setting up headers again. We have a method called setHeader()
public void setHeader(String headerName, String headerValue)
which takes a name and a corresponding value. That will replace any header which was used earlier(same headername). Same header could have multiple values, that could also be possible. For that we have another method called addHeader().
public void addHeader(String headerName, String headerValue)
Both these methods, setHeader() and addHeader() have convenient form in case the header values are of integer type or date type. the convenience methods are addIntHeader() or setIntHeader().
public void addIntHeader(String headerName, int headerValue) public void setIntHeader(String headerName, int headerValue) same way we have the addDateHeader() and setDateHeader() methods also.
public void addDateHeader(String headerName, long headerValue) public void setDateHeader(String headerName, long headerValue)
Talking about the development of the servlet. We have seen two ways of creating a Servlet. One was using implementation of Servlet. Another was extending GenericServlet. You could even use the BaseServlet that we have developed earlier.
HttpServlet
In javax.servlet.http package, there is a class called HTTPServlet. This is the class which extends from GenericServlet. It is an abstract class with no abstract methods.Let’s see how it overrides some of the methods from GenericServlet and how it adds few more methods to it. service() was abstract in the GenericServlet.
public void service(ServletRequest req, ServletResponse res)
The parameters were ServletRequest and ServletResponse which is actually from the generic part of the servlet API. we have that method being overridden here to simply invoke another form of service() method. We have one more service() method added in the HttpServlet class.
protected void service(HttpServletRequest request, HttpServletResponse response)
This service() method has parameters of type HttpServletRequest and HttpServletResponse. The implementation of the earlier service method is to simply cast the ServletRequest and ServletResponse parameters to HttpServletRequest and HttpServletResponse and then invoke the other service method.
public void service(ServletRequest req, ServletResponse res) { service((HttpServletRequest) req, (HttpServletResponse) res);
}
This new service method takes HttpServletRequest and HttpServletResponse as parameters. What does this service() methods do? This service method which has parameters of HttpServletRequest and HttpServletResponse is implemented to identify from the request which is an instance of HttpServletRequest, the Http method which was used by the client. In the HttpServletRequest interface we have a method called getMethod which returns the Http method used by the client.
public String getMethod()
The implementation of the service method would identify the http method and it would then invoke the corresponding doXXX method, where XXX is the http method.
Depending on the http request we may be interested in handling the request differently. We may not want to handle some type of http method in request. To make this possible what has been done here is, the service method which takes HttpServletRequest and HttpServletResponse as parameter has been written in a manner, where the first thing it does is, looks at the http request, find out the http method, what is the http method which is used and then it says, if the method is GET, then I will use the doGet method, if the method is POST, then I will use the doPost method. For each of the http method like GET, POST, HEAD, TRACE, etc., there is a separate method in our HttpServlet class. So we have various kinds of do methods doGet, doPost, doHead, doTrace, and so on. The service method detects what is the method in the request and then accordingly invokes the specific do mthod. So, what is done in the do methods here? What is the default implementation of the doGet method? The doGet method which we have in the HttpServletRequest is simply implemented to send an error to say that GET method is not supported. So implementation of doGet is to send error to client that GET method is not supported, implementation of doPost is to send an error to the client saying POST method is not supported, and so on. Why such an implementation of these methods? The idea here is that when you want to write a Servlet, you will create a sub-class of the HttpServlet and whichever http method you want to support, you should be overriding that, the others by default would not be supported.
Now, what are the ways to develop a Servlet? We have now all the options available, first option, what we did with HelloServlet? The option we used was implementing the Servlet interface. Next option extending from GenericServlet,b ut since we know we have Http Protocol, we need not go for this option, we could create Servlet by extending the HttpServlet, and here again we have the option of overriding any of those two service methods, none of those are final, or we can override the required do method. If we want to support a specific http method, eg. We are interested in handling on the GET method, or may be interested in handling more than one method eg. Interested in handling GET as well POST, and both of them doing the same thing, we could override both the doGet method as well as the doPost method and one of them may simply invoke the other one, or we may have two different ways of handling both the methods.
There is one more method added in the HttpServlet, called lastModified to return long. This is simply to give a timestamp what you consider for this URL what is the last modification date and time. By default it would return a -1 indicating, that this content cant be cached.
So, in this module we have covered the HttpServletRequest, the HttpServletRequest and the HttpServlet, how it extends from the GenericServlet and implements the service method.
you can view video on HTTP specific API for Servlets |
Suggested Reading:
- Core Servlets and Java Server Pages Volume1 by Marty Hall & Larry Brown, Second Edition, Pearson Education.
- Inside Servlets by Dustin R Callaway, Pearson Education.
- Java Server Programming for Professionals by Ivan Bayross, Sharanam Shah, Cynhthia Bayross and Vaishali Shah Shroff Publishers and Distributros.
- http://download.oracle.com/otndocs/jcp/servlet-3.0-fr-oth-JSpec/