From World of VOC - Wiki

Jump to: navigation, search

Contents

Using the SessionVOC from Java Servlets

Preliminaries

We assume that you are familiar with Java Servlet technology and that you have set up a triagens SessionVOC server.

For the latter refer to ...

Introduction to triagens SessionVOC server

In a typical szenario, triagens SessionVOC server is used to store session information over the calls that reach your web application from the user's browser.

In this text we will describe how a Java Servlet application can access the SessionVOC server via the Java Client API.

Using SessionVOC has several advantages over the session handling that is already built into Java servlet technology:

  1. Since the SessionVOC interface to the web application is based on standard technologies (http(s), JSON) components written in languages other than Java can also share the same session pool - so far interfaces for PHP, Ruby and JavaScript exist.
  2. Since the session information are kept in a separate server with a session id being the only piece of information that connects the browsers with the session database the web application can easily migrate from one server to another - a feature useful for both load sharing and high availability.
  3. With the Standard Edition of triagens SessionVOC load-sharing and high-availability are supported for the session service itself.
  4. Persistence of user data is automatically managed by SessionVOC.
  5. Additional features simplify writing secure web applications:
    1. Form data to support multi page forms
    2. Challenge response login
    3. One time tokens

Using SessionVOC from Java servlets

Basic considerations

As described above the browser must keep a piece of information - the session id - to tell the web application in which session it "lives". In our example we assume that this information is kept in a cookie (that is only valid in the current browser session).

Once you have obtained a session you have access to two distinct sets of data, both of them are configurable via the server:

  1. The values kept in the transData set live as long as your session - once it is lost the data in there is lost, too.
  1. The values kept in the userData set are available after a successful login (until a logout) in the session. They are persistently stored in a relational database managed by the SessionVOC server.
Imports

The following examples assume that you import the de.triagens.sessionvoc and de.triagens.sessionvoc.servletutils packages by

import de.triagens.sessionvoc.*;
import de.triagens.sessionvoc.servletutils.*;

into your Java source.

Turning off your servlet container's session handling

When using SessionVOC you will most probably no longer use the session handling that is provided by the Java Servlet API.

To avoid unnecessary data transfers you should ensure that your servlet container's session handling is really turned off. E.g., with Apache Tomcat v7.0 we noticed that the JSESSION cookie is sent to the browser even before a servlet calls getSession().

This can be avoided by placing <Context path="/Path_where_your_app_is_deployed" cookies="true" /> into your context.xml.

Initializing the connection to the SessionVOC server

The Java API to SessionVOC provides an object that cares for setting up the connection between the client web application and the SessionVOC server. It keeps a connection to the SessionVOC server (reopened if necessary) and some basic information about the data structures provided to avoid the necessity to set up all these things for every call.

This object will typically be instantiated once for the whole web application. For proper initialization of this object we provide the servlet de.triagens.sessionvoc.servletutils.Initializer.

Deploy it into your web application by placing the following lines into your web application's web.xml:

<context-param>
 <description>Hostname of the triagens SessionVOC server</description>
 <param-name>sessionvoc-server</param-name>
 <param-value>Enter the hostname or IP address of the server running the SessionVOC here</param-value>
</context-param>
<context-param>
 <description>Port of the triagens SessionVOC server</description>
 <param-name>sessionvoc-port</param-name>
 <param-value>Enter the port on which the SessionVOC server listens here - in standard installation this is 8208</param-value>
</context-param>

<servlet>
 <servlet-name>triAGENS SessionVOC Initializer</servlet-name>
 <servlet-class>de.triagens.sessionvocjsp.Initializer</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>

With the two context-parameter sessionvoc-server and sessionvoc-port we configure the location of the SessionVOC server. These parameter are evaluated by the de.triagens.sessionvocjsp.Initializer servlet that is run at startup of the web application because load-on-startup<code> is set to <code>1. The servlet should never be called again.

"Binding" your servlet to a SessionVOC session

When the doXXX methods of your servlet are invoked you need to object via that you can access the session data and perform action like logging in and out.

Thanks to the static getSession-methods in the class ServletUtils getting this object is quite easy:

  ServletSession vocsession = ServletUtils.getSession( this, request, response );

(Note: We name the object vocsession instead of simply session because in a JSP the variable session is already defined.)

Behind the scences getSession does the following:

  • get the "connection" object that has been initialized by ServletUtils.Initializer
  • look for a cookie named sid in the request
    • if there is such a cookie "bind" vocsession to this session
    • if there is no such cookie
      • "bind" vocsession to a newly created session
      • save the sid of the session in a cookie

In the case that there a cookie with a sid but the session has expired on the SessionVOC server (or - for whatever reason - the cookie contains a sid that has never been valid) you will silently be bound to a new session. E.g., this means that the user will have to login to your application again. A way how to handle this silently (simply display the login page again) is included in the example later (and for sure should be integrated into every web application).

In case you want to explicitly inform the user about the fact that the session has expired you have a second form to invoke getSession with an additional parameter

  ModifiableBoolean reloaded = new ModifiableBoolean();
  ServletSession vocsession = ServletUtils.getSession( request, response, reloaded );

and then ask for reloaded.getValue().

TBD: Gibt es einen eleganten Weg diesen ModifiableBoolean zu umgehen?

Note that ServletSession is a wrapper to de.triagens.sessionvoc.Session that maps the SessionVOCExceptions thrown there into ServletExceptions - thus you don't have to care for catching them. In a summary, to get a SessionVOC session in your doPost-method(e.g.) of servlet your code will more or less look like

...

import de.triagens.sessionvoc.*;
import de.triagens.sessionvoc.servletutils.*;

...

public class MyServlet extends HttpServlet {

...

  public void doPost( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException {
    ModifiableBoolean reloaded = new ModifiableBoolean();
    ServletSession vocsession = ServletUtils.getSession( request, response, reloaded );
    if ( reloaded.getValue() ) {
      // inform the user that the session expired
    } else {
      //if applicable, check if the session is loggedIn
      //check the parameter
      //do your work
    }
  }

...

}

Overview about the sample application

Before we now dig into the details here's a short overview over the servlet application, where you can log, display your first- and lastname and change your mobile no:

               /Login                  /UserData               /Logout

             +----------------+      +----------------+      +----------------+
             | Login.java     |      | UserData.java  |      | Logout.java    |
             |                |      |                |      |                |
Controller   |                |      |                |      |                |
             |                |      |                |      |                |
             |                |      |                |      |                |
             +----------------+      +----------------+      +----------------+
               |                       |
               | forward               | forward
               |                       |
             +----------------+      +----------------+
             | Login.jsp      |      | UserData.jsp   |
             |                |      |                |
View         |                |      |                |
             |                |      |                |
             |                |      |                |
             +----------------+      +----------------+

Login into a SessionVOC session

Basically, you invoke the method login( uid, password ) on the session object. It returns if this has been successful in a boolean.

Before calling login you should check that you are not already logged in since a login on an already authenticated session fails.

You can either solve this by logging the session off (call vocsession.logout()), by redirecting the requested to a controller inside the "logged in"-area, or by issuing an appropriate warning.

TBD: Ist der zweite Weg wirklich empfehlenswert? (der ist aktuell im Beispiel implementiert;-)

Setting session data

There are a several methods to get and put data into your session:

They all take a key (the name of the variable) as the first argument, the setters take a value as a second Argument.

So far the SessionVOC Java API supports the following datatypes:

Datatype getter setter
Variant Object getTransData( String key ) void setTransData( String key, JSONObject value )
void setTransData( String key, JSONArray value )
Object getUserData( String key ) void setUserData( String key, JSONObject value )
void setUserData( String key, JSONArray value )
String/Variant String getTransDataString( String key ) void setTransData( String key, String value )
String getUserDataString( String key ) void setUserData( String key, String value )
Long/Variant Long getTransDataLong( String key ) void setTransData( String key, Long value )
Long getUserDataLong( String key ) void setUserData( String key, Long value )
Double/Variant Double getTransDataDouble( String key ) void setTransData( String key, Double value )
Double getUserDataDouble( String key ) void setUserData( String key, Double value )
Boolean/Variant Boolean getTransDataBoolean( String key ) void setTransData( String key, Boolean value )
Boolean getUserDataBoolean( String key ) void setUserData( String key, Boolean value )
Datetime/Variant java.util.Date getTransDataDate( String key ) void setTransData( String key, java.util.Date value )
java.util.Date getUserDataDate( String key ) void setUserData( String key, java.util.Data value )

For more generic operations there's a number of methods that allow the programmer to ask the session for the names of the variables and their types.

Note that it is possible to access the session from JSP as well. In our example we didn't to so since we don't have to put the extra burden (import, get session) into the JSP. Instead we pass all values via attributes from the controller to the view.

When you are done with changing the session you have to call save() on it.

In the sample application we read the user's name and surname, and we read and write the user's mobile no in the userData area. Thus, the user's mobile no will be persistently stored in the SessionVOC database (the SessionVOC server has to be correctly configured to do so).

To pass a value from one controller to another we use the message-String in the transData area. E.g., the Logout-controller passes the status of the logout ("Logged out" vs. "You are no logged in") to Login-Controller by putting an appropriate String into the transData area before calling the redirect.