4. The servlet's environment




4.1 Understand more details of the HTTP protocol

All HTTP methods

Although you only use GET and POST in the real world, the others may come up. Only POST is NOT idempotent (can be called multiple times without side effects).

Method Description
GET Asks to get the resource at the requested URL
POST Send data to the server for processing by an active resource.
HEAD Asks for only the header part of whatever a GET would return.
TRACE Asks for a loopback of the request message, so that the client can see what’s being received on the other end, for testing or troubleshooting.
PUT The data sent using PUT is stored on the server by the name given in the request.
DELETE Delete the resource at the requested URL
OPTIONS Asks for a list of the HTTP methods to which the thing at the requested URL can respond.
CONNECT Connect for the purposes of tunneling (not implemented by Servlets)

Common MIME types

text/html
application/pdf
video/quicktime
application/java
image/jpeg
application/jar
application/octet-stream
application/x-zip

HTTP Request

  • GET should be used for insecure, idempotent links to existing pages. Works with the Back button and bookmarking. Limit on amount of data that can be sent
  • POST should be used for modification purposes, such as adding, updating and deleting. Also required for complex forms
  • HttpServletRequest extends ServletRequest

GET method

GET URL?param=value&param2=value2 HTTP/1.1
Request headers

Request headers may include:

  • Host
  • User-Agent
  • Accept
  • Accept-Language
  • Accept-Encoding
  • Accept-Charset
  • Last-Modified: used with Cache-Control for caching
  • Cache-Control: no-cache, no-store or max-age=(seconds)
  • Connection

POST method

  • HttpServletResponse extends ServletResponse

POST URL HTTP/1.1
Request headers

param=value&param2=value2 (body)

HttpServletRequest Class

Not comprehensive, only most important listed. Full list: http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html

inherited from ServletRequest

getAttribute(String) : Object
getContentLength() : int
getInputStream() : ServletInputStream // An input stream from the request
getLocalPort() : int
getParameter(String) : String // get first (and only, in most cases) value for a parameter
getParameterNames() : Enumeration
getParameterValues(String) : String[]
getRequestDispatcher() : RequestDispatcher // can handle relative URLs, unlike ServletContext.getRequestDispatcher()
getNamedDispatcher(String) :  // Returns a RequestDispatcher object that acts as a wrapper for the named servlet.
getInputStream()
getReader()

in class itself

getContextPath() : String
getCookies() : Cookie[] // The cookies associated with this request
getQueryString() : String
getSession(boolean) : HttpSession // The session associated with this client. true will create new session if it doesn't get
getMethod() : String // The HTTP Method of the request
 
getPathInfo() : String // the PathInfo part of the request path is the part which doesn't belong to the ContextPath nor the ServletPath (AKA requestpath) and ends before the query string.
 
long getDateHeader(String name)    Returns the value of the specified request header as a long value that represents a Date object.  
String getHeader(String name)    Returns the value of the specified request header as a String.  
Enumeration getHeaderNames()    Returns an enumeration of all the header names this request contains.  
Enumeration getHeaders(String name)    Returns all the values of the specified request header as an Enumeration of String objects.  int getIntHeader(String name)    Returns the value of the specified request header as an int.  If there is no header by this name, it returns "-1" and if the value cannot be converted to an int, it throws a NumberFormatException.

HTTP Response

HTTP/1.1 200 OK (protocol, status code, status text)
Response headers (Content-type, etc.)

Response body (e.g. HTML)

Response headers may include:

  • Set-Cookie
  • Content-Type: a MIME type, which must have appeared in the Request Accept header.
  • Content-Length
  • Data
  • Server
  • Connection

MIME type stands for Multipurpose Internet Mail Extensions

HttpServletResponse Class

Not comprehensive, only most important listed. Full list: http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html

Generally, two ways to use the response:

  1. Write HTML or other content directly: setContentType(mime) [always do this first], getWriter() and out.println() for HTML, response.getOutputStream() for binary content
  2. Redirect to JSP: using getRequestDispatcher(), forward(request, response)
// inherited from ServletResponse
getBufferSize() : int
setContentType(String) : void
setContentLength(int) : void
getOutputStream() : ServletOutputStream
getWriter() : PrintWriter
// in class itself
addCookie(Cookie) : void
addHeader(String name, String value) : void
encodeRedirectURL(String url) : String
sendError(int) : void / sendError(int sc, String msg) // triggers servlet container to generate error page
setStatus(int) : void // sets value of status header
isCommited() : boolean


4.2 Understand fundamentals of HTML forms

  • method may be POST or GET, default with no method is GET
  • input fields have a name parameter which is used by request.getParameter()
  • request.getParameterValues() gets all form names in a String[]
<form method="POST" action="/myform">
  <select name="color">
  <option>light
  <option>amber
  <option>brown
  <option>dark
  </select>
  <select name="body">
  <option>light
  <option>medium
  <option>heavy
  </select>
  <input type="submit" />
</form>



4.3 Understand fundamentals of the HttpServlet and related APIs

See also: 9.2 Describe and use more advanced elements of the servlet APIs

http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html

Lifecycle

  1. init(): called only once to allow setup; override if setting up resources. Gives the servlet access to the ServletConfig and ServletContext objects, which the servlet needs to get information about the servlet configuration and the web app
  2. service(): calls either doGet() or doPost(); generally should not be overriden
  3. destroy(): called only once to allow cleanup, service() threads completed: override if closing resources

The following is the sequence of things that happen when you invalidate a session:

  1. Container calls sessionDestroyed() on all HttpSessionListeners configured in web.xml (in the reverse order they are declared in web.xml). Notice that although the method name is sessionDestroyed, the session is not destroyed yet. It is about to be destroyed. (Note that sessionCreated is called on the listeners in the order they are declared in web.xml)
  2. The container destroys the session.
  3. The container calls valueUnbound() on all the session attributes that implement HttpSessionBindinglistener interface.

Inheritance hierarchy

Servlet => GenericServlet => HttpServlet

Servlet interface methods

service(ServletRequest, ServletResponse) (abstract method)
init(ServletConfig) throws ServletException
destroy() // throws NO exceptions
getServletConfig()
getServletInfo()

GenericServlet abstract class methods

service(ServletRequest, ServletResponse) throws ServletException, IOException
init(ServletConfig)
init()
destroy()
getServletConfig()
getServletInfo()
getInitParameter(String)
getInitParameterNames()
getServletContext()
log(String) //  this version prepends the servlet name to the message.
log(String, Throwable) //  this version prepends the servlet name to the message.

HttpServlet class methods

Signatures of all the doXxx() methods are same. These methods are protected, return void, take HttpServletRequest and HttpServletResponse as parameters, and throw IOException and ServletException. Notice that they are as protected (not public):

protected void doXXX(HttpServletRequest, HttpServletResponse) throws IOException, ServletException
service(HttpServletRequest, HttpServletResponse)
service(ServletRequest, ServletResponse)
doGet(HttpServletRequest, HttpServletResponse)
doPost(HttpServletRequest, HttpServletResponse)
doHead(HttpServletRequest, HttpServletResponse) // by default, calls doGet()
doOptions(HttpServletRequest, HttpServletResponse)
doPut(HttpServletRequest, HttpServletResponse)
doTrace(HttpServletRequest, HttpServletResponse)
doDelete(HttpServletRequest, HttpServletResponse)
getLastModified(HttpServletRequest)

Error handling servlet

An error handler servlet should have access to 4 attributes:

  • javax.servlet.error.status_code
  • javax.servlet.error.exception
  • javax.servlet.error.servlet_name
  • javax.servlet.error.request_uri.
So, if you are forwarding the request to an error handling servlet manually using RequestDispatcher, you should set the above attributes in the request before forwarding the request to the servlet.


4.4 Write code that manages client sessions and cookies

The Container takes care of generating the session ID, creating a new Cookie object, stuffing the session ID into the cookie, and setting the cookie as part of the response. And on subsequent requests, the Container gets the session ID from a cookie in the request, matches the session ID with an existing session, and associates that session with the current request.

Sessions

Sessions are generally set to expire after 15 or 20 minutes and use cookies. A session whose timeout period has been set to -1 will never expire. If cookies are disabled by the client, URL rewriting or hidden form fields will be used.

You can set session timeout in two ways:

<session-config>
    <session-timeout>15</session-timeout>
</session-config>
session.setMaxInactiveInterval(20*60); // for a single session, not all
// sending a session cookie in the response
HttpSession session = request.getSession();
 
/*
    Getting the session ID from the request (NOT a typo, exactly the same method)
    If the request includes a session ID cookie, find the session matching that ID, otherwise create a new session
*/
HttpSession session = request.getSession();
 
// use false as parameter to only get pre-existing session
request.getSession(false);
 
System.out.println(session.isNew());
 
// Alternatively, get a session from one of the Session listeners, e.g.
public void sessionCreated(HttpSessionEvent event) {
    HttpSession session = event.getSession();
    // event handling code
}

Session lifecycle

Note all sessions go through all stages.

1. Session created
Event: HttpSessionEvent
Listener: HttpSessionListener

2. Attributes added/removed/replaced
Note: this interface should be implemented by entity classes, not standalone listeners.
Event: HttpSessionBindingEvent
Listener: HttpSessionAttributeListener and HttpSessionBindingListener
Methods:

  • HttpSessionAttributeListener: attributeAdded(), attributeRemove(), attributeReplaced()
  • HttpSessionBindingListener: valueBound(), valueUnbound()

3. Migration
Event: HttpSessionEvent
Listener: HttpSessionActivationListener
Called just before sessions are passivated or activated in order to prepare attributes for migration to another VM.

4. Session destroyed
Event: HttpSessionEvent
Listener: HttpSessionListener

Other
ServletContextListener uses ServletContextEvent
ServletContextAttributeListener uses ServletContextAttributeEvent
ServletRequestListener uses ServletRequestEvent
ServletRequestAttributeListener uses ServletRequestAttributeEvent

HttpSession interface

The most common methods only:

getAttribute(String)
setAttribute(String, Object)
removeAttribute(String)
getAttributeNames()
getId()
setTimeout
 
getCreationTime() // Returns the time the session was frst created
getLastAccessedTime() // Returns the last time the Container got a request with this session ID (in milliseconds).
/* maximum time, in seconds, until sessions time out. A negative time indicates the session should never timeout. */
setMaxInactiveInterval(int) 
getMaxInactiveInterval() // Returns the maximum time, in seconds, that is allowed between client requests for this session.
invalidate() // Ends the session. This includes unbinding all session attributes currently stored in this session.

URL rewriting

URL rewriting is used if the user does not have cookies enabled. The jsessionid parameter is added to the query string of URL dynamically by the container. This only works if URLs is encoded, e.g.

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    HttpSession session = request.getSession();
    out.println("<html><body>");
    out.println("<a href=\"" + response.encodeURL("/BeerTest.do") + "\">click me</a>");
    out.println("</body></html>”);
}

Use response.encodeRedirectURL() for redirects.

SSL

<session-config>
    <tracking-mode>SSL</tracking-mode>
</session-config>

HttpOnly

  • It prevents JavaScript running within the browser from accessing the cookie.
  • Can be delivered using either HTTP or HTTPS

HttpOnly cookies indicate to the client that they should not be exposed to client-side scripting code (i.e. the JavaScript executing in the browser. For example, you cannot do "document.cookie" in JavaScript code to get access to HttpOnly cookie.). The use of HttpOnly cookies helps mitigate certain kinds of cross-site scripting attacks.

<session-config>
   <cookie-config>
     <http-only>true</http-only>
   </cookie-config>
 </session-config>

Session tracking modes

getDefaultSessionTrackingModes() returns the session tracking modes that are supported by default for this ServletContext (i.e. the modes that are configured), while getEffectiveSessionTrackingModes() gets the session tracking modes that are in effect for this ServletContext.

Cookies

// Creating a new Cookie
Cookie cookie = new Cookie("username", name);
cookie.setPath(request.getContextPath()+"/subpath");   // must include context path for correctness
response.addCookie(cookie);
 
// Setting how long a cookie will live on the client
cookie.setMaxAge(30*60); // seconds
 
// Getting the cookie(s) from the client request
// unfortunately, no getCookie(name) method
Cookie[] cookies = request.getCookies();
 
for (int i = 0; i < cookies.length; i++) {
    Cookie cookie = cookies[i];
    if (cookie.getName().equals("username")) {
        String userName = cookie.getValue();
        out.println("Hello " + userName);
        break;
    }
}

Interfaces and classes

Relevant interfaces/classes and methods are below.

javax.servlet.http.HttpServletRequest

getCookies()

javax.servlet.http.HttpServletResponse

addCookie()

Sending the cookie to the client

Cookie cookie = new Cookie("name", name);
response.addCookie(cookie); // not a String, Cookie object

javax.servlet.http.Cookie

Cookie(String, String) [constructor]
String getDomain()
int getMaxAge()
String getName()
String getPath()
boolean getSecure()
String getValue()
void setDomain(String)
void setMaxAge(int)
void setPath(String)
void setValue(String)
 
void setSecure(boolean)
/* Indicates to the browser whether the cookie should only be sent using a secure protocol, such as HTTPS or SSL. 
The default value is false. */
 
void setHttpOnly(boolean)
/* HttpOnly cookies are not supposed to be exposed to client-side scripting code, and may therefore help mitigate 
certain kinds of cross-site scripting attacks. */






Comments

If you have questions, corrections, information or examples to add, please comment below.

Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License