Behind the event-driven processing model of Vaadin lies the Java Servlet API,
which is based on processing HTTP requests. These requests are normally
hidden from Vaadin applications, but can be caught using the
HttpServletRequestListener
interface. You must
implement the interface in your application class. The two methods defined in
the interface, onRequestStart()
and
onRequestEnd()
, allow processing the request before
and after other processing.
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.vaadin.Application; import com.vaadin.terminal.gwt.server.HttpServletRequestListener; import com.vaadin.ui.*; public class HttpServletRequestApplication extends Application implements HttpServletRequestListener { @Override public void init() { System.out.println(" Application.init() called."); Window main = new Window("URI Fragment Example"); setMainWindow(main); setTheme("book-examples"); // Does nothing but causes a request Button button = new Button ("Make a request"); main.addComponent(button); } public void onRequestStart(HttpServletRequest request, HttpServletResponse response) { System.out.println("[Start of request"); System.out.println(" Query string: " + request.getQueryString()); System.out.println(" Path: " + request.getPathInfo()); } public void onRequestEnd(HttpServletRequest request, HttpServletResponse response) { System.out.println(" End of request]"); } }
The onRequestStart()
is called for the first time
when the application class is loaded but the init()
is not yet called. This can be seen in the output of the above code example:
[Start of request Query string: null Path: null Application.init() called. End of request] [Start of request Query string: repaintAll=1&sh=1050&sw=1680&cw=500&ch=300&vw=500 Path: /UIDL/ End of request] [Start of request Query string: windowName=1071684214 Path: /UIDL/ End of request]
The first call is a regular HTML page load, so the URL path is simply the
application path. The subsequent calls are AJAX calls made using the UIDL
protocol, so the request path includes the /UIDL/
part. This is
important to know when using cookies, as explained later.
The HttpServletRequest
object provides access to
the request data, such as request headers, path info, and query string, as
well as to some higher-level information such as cookies.
The HttpServletResponse
object is somewhat
different, as most write operations write data directly to the output
stream of the server request. It is therefore possible to add new headers
and cookies in the onRequestStart()
, and make
other settings, but not later on, especially not in the
onRequestEnd()
, as all the UIDL response data has
already been written to the output stream. The framework writes the UIDL
response to the output stream of the response before
calling onRequestEnd()
. You therefore have to be
careful when writing to the response object. You can usually write to it
when handling component events in listeners, as is done in the cookie
example later.
While it is theoretically possible to redirect the output stream of the response object to write custom data to the response, you should never need to do that, as it would break the UIDL communication protocol.
The servlet request and response objects are defined in the Java Servlet API. Please refer to its documentation for more detailed information.
Setting and reading cookies is one of the typical uses of
HttpServletRequestListener
. The application gets
the HttpServletRequest
object containing the
cookies in the onRequestStart()
method.
You normally set a cookie in an event listener. As the request object
is a transient object that exists only for the duration of the
request, it is not accessible from the
Application
object. The only way to access it
is to store it in onRequestStart()
, as done
in the following example.
public class CookieExampleApplication extends Application implements HttpServletRequestListener { HttpServletResponse response; public void onRequestStart(HttpServletRequest request, HttpServletResponse response) { // Store the reference to the response object for // using it in event listeners this.response = response; ... } ...
We can then use the reference to set or delete cookies in event
listeners. Notice that the cookie path property
is automatically set to the application path (such as
/book-examples/cookies
) on the first request, but
contains the UIDL
subpath on subsequent calls
(such as /book-examples/cookies/UIDL
). As the
cookies are matched against this path, you may need to set the path
explicitly with setPath()
.
newuser = new TextField ("Give a user name"); login = new Button("Login"); login.addListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { Object value = newuser.getValue(); if (value != null && ! "".equals((String)value)) { username = (String) value; Cookie cookie = new Cookie("username", username); // Use a fixed path cookie.setPath("/book-examples"); cookie.setMaxAge(3600); // One hour response.addCookie(cookie); System.out.println("Set cookie."); newuser.setEnabled(false); login.setEnabled(false); restart.setEnabled(true); logout.setEnabled(true); } } }); loginrow.addComponent(newuser); loginrow.addComponent(login);
Removing cookie can be set in similar way by setting the maxAge property to zero.
// Delete the cookie Cookie cookie = new Cookie("username", username); cookie.setPath("/book-examples"); cookie.setMaxAge(0); // Delete response.addCookie(cookie);
Reading a cookie can be done in the
onRequestStart()
event. As this method is
called also on the first client request before the application is
initialized, it is possible to read user identification cookies and
such on the first request.
public class CookieExampleApplication extends Application implements HttpServletRequestListener { String username; public void onRequestStart(HttpServletRequest request, HttpServletResponse response) { if (username == null) { Cookie[] cookies = request.getCookies(); for (int i=0; i<cookies.length; i++) { if ("username".equals(cookies[i].getName())) // Log the user in automatically username = cookies[i].getValue(); } } } ...
Notice that the request path is the application path (such as
/book-examples/cookies
) on the first request, but
contains the UIDL
subpath on subsequent AJAX
calls (such as /book-examples/cookies/UIDL
). So,
if you have set the cookie in an AJAX request without setting the
cookie path explicitly to such that does not contain the
UIDL
subpath, the cookie will be filtered out on
the initial onRequestStart()
call.