viernes, 4 de noviembre de 2011

WicketSession fuera de Wicket

Wicket tiene su propio objeto de sesión que se puede utilizar dentro de una aplicación para guardar elementos entre distintas llamadas de un mismo cliente. Este objeto será una org.apache.wicket.Session o algún otro objeto que la extienda como WebSession o un objeto propio.

Mientras no nos salgamos de la aplicación de Wicket todo va bien y tendremos la sesión disponible... pero ¿y si tenemos que enviar al usuario a otra parte de nuestro servidor que se sale de nuestra aplicación? A un servlet distinto o un formulario de otra parte, por ejemplo. En ese caso perderemos la sesión y no podremos saber que se trata del mismo que viene de la aplicación Wicket.

Hay una solución para este problema y que nos dejará la sesión disponible en cualquier otro lugar (servlets, jsps...) y es a través de un filtro especial llamado WicketSessionFilter que hará justo lo que deseamos, transportar la sesión a otros lugares.
Para usarlo, debemos configurarlo primero en el archivo web.xml del servidor de aplicaciones:

<!-- The WicketSesionFilter can be used to provide thread local access to servlets/ JSPs/ etc -->
  <filter>
    <filter-name>WicketSessionFilter</filter-name>
    <filter-class>org.apache.wicket.protocol.http.servlet.WicketSessionFilter</filter-class>
    <init-param>
      <param-name>filterName</param-name>
      <!-- expose the session of the input example app -->
      <param-value>FormInputApplication</param-value>
    </init-param>
  </filter>
 
  <!-- couple the session filter to the helloworld servlet -->
  <filter-mapping>
    <filter-name>WicketSessionFilter</filter-name>
    <url-pattern>/helloworldservlet/*</url-pattern>
  </filter-mapping>

En el parámetr filterName, debemos poner el valor de otro filtro que ya tengamos en nuestra aplicación (la verdad que esto no lo se muy bien por qué, pero es como me ha funcionado) y el resto de campos se puede ver bastante bien en el ejemplo: el mapping al servlet en el que queremos tener disponible nuestra sesión de Wicket.

Ahora ya se puede acceder a la sesión desde el servlet de la siguiente manera:

Session wicketSession = Session.get();

Que dentro de un servlet quedaría algo así:

public class HelloWorldServlet extends HttpServlet
 {
        public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,
                IOException
        {
                res.setContentType("text/html");
                PrintWriter out = res.getWriter();
                String message = "Hi. " +
                        (Session.exists() ? " Veo la sesion de Wicket " + Session.get() + "."
                                : " No encuentro la sesion de Wicket.");
                out.println(message);
                out.close();
        }
 }


Fuente: http://wicket.apache.org/apidocs/1.4/org/apache/wicket/protocol/http/servlet/WicketSessionFilter.html