2011-05-11 10 views
5

Digamos que tenemos una aplicación web respaldada por un motor/contenedor de servlet como Tomcat. Un usuario inicia sesión. Se carga el registro de la base de datos para ese usuario (representado por una instancia del usuario de la clase, digamos) y podemos almacenarlo como un atributo de sesión con la clave "usuario actual", configurarlo una vez y usarlo para manejar solicitudes posteriores. Además, ponemos más objetos en el atributo de la sesión. Bastante básico.Aplicación web Tomcat: ¿almacenar objetos como objetos definidos por el usuario o ID simples para persistir en las sesiones de usuario a través del reinicio del servidor?

Ahora, si tenemos que implementar algún código nuevo y reiniciar Tomcat ... Las sesiones de usuario siguen intactas después del reinicio (restaurado desde el disco/base de datos) siempre que no cambiemos ninguna de las clases cuyas instancias se almacenan en la sesión de usuario. Pero este es un gran problema. No quiero que los usuarios pierdan sus sesiones con la publicación de un nuevo código.

Para evitar este problema, supongo que puedo almacenar en el objeto de sesión solo instancias de clases que se supone que nunca cambian (como almacenar la ID del usuario conectado como un Entero a diferencia de una instancia del Clase de usuario). Entonces nunca me encontraría con el problema de no poder deserializar el objeto de sesión al reiniciar. Pero esto hace las cosas un poco más complicadas ya que ahora tengo que usar el ID para cargar el objeto real desde la base de datos, etc. (y con el almacenamiento en caché, el impacto en el rendimiento no es realmente un problema).

Es esto lo que típicamente se hace para solucionar este problema?

+0

el primer escenario (almacenamiento de objetos completos) requiere un poco de inversión de tiempo para comprender cómo funciona la serialización. Si se hace correctamente, nunca debería "perder" nada en una nueva versión. – bestsss

Respuesta

3

solución simple

como usted sugiere, la carga sólo el ID de usuario en la sesión, y utilizar el servicio de caché como ehcache para recuperar los objetos de usuario. Si el objeto de usuario no existe, se cargará la primera vez, pero luego se almacenará en caché y las solicitudes posteriores serán bastante rápidas. Si le preocupan los cambios en su clase de usuario, configure su memoria caché solo para que se restablezca entre los reinicios del servidor.

solución Plataforma

Ven a ver terracota (http://www.terracotta.org/). Si puede implementar sus sesiones en su plataforma, éstas le permitirán mantenerlas entre los reinicios del servidor, así como también actualizar la clase de usuario real mientras mantiene los campos antiguos. Cosas geniales una vez que lo tienes funcionando.

Tenga en cuenta que la integración de Terracotta no es simple y no es para principiantes. Sin embargo, los beneficios son la escalabilidad y la alta disponibilidad que todas las aplicaciones web requieren en general.

+0

Esto es exactamente lo que terminé haciendo. Acabo de cambiar la implementación de la función de envoltura para obtener/configurar información de usuario. Uso Spring/Hibernate, por lo que activar EhCache fue muy fácil. Gracias por la información sobre Terracota. – n00b

1

Situación interesante y buena pregunta. Por lo general, por lo que he visto en entornos empresariales, las sesiones generalmente se cancelan después de implementar una nueva versión de la aplicación web. Dado que se trata de una nueva implementación, el servidor de aplicaciones generalmente no conoce la diferencia entre una nueva versión de la aplicación web. aplicación y una nueva versión. No creo que sea una buena idea si los servidores mantienen las sesiones, ya que puede tratarse de una aplicación completamente diferente, para la cual el usuario puede no tener permisos de acceso, etc., por lo que esto podría ser un problema de seguridad.

Sin embargo, vamos a suponer que las sesiones se persistieron y se podrían restaurar incluso para nuevas implementaciones. La forma en que describes suena muy bien, también podrías hacerlo un poco más sofisticado, como verificar si la sesión tiene objetos viejos que necesitan ser convertidos (o cargados de la base de datos de nuevo) en función de su versión. En Java, haría todo lo posible para que sus clases sean compatibles con binarios, por lo que la nueva versión de la aplicación aún puede deserializarla. Para eso son writeObject/readObject.

Otra idea es almacenar la "sesión" en su propio formato de datos en la base de datos y tener la sesión solo para datos livianos, como la autenticación de usuario y su propia identificación de sesión de la aplicación. Sin embargo, nunca lo he visto en una aplicación Java, pero hace posible hacer lo que quiera y realizar los pasos de migración en el momento del despliegue para migrar los datos al nuevo formato. Junto con las cookies de auto-login/remember-me, sus usuarios no notarían ninguna diferencia.

2

En lo que va de serialización, siempre y cuando no cambie el formato de serialización que no será un problema. De lo contrario, obtendrá la temida InvalidClassException. Lo que usted tiene que hacer es:

  1. Conjunto serialVersionUID una en cada objeto que está serializando: siempre y cuando no cambie drásticamente los campos de la clase entre reinicios esto debería ser suficiente.
  2. Sobrescribe los métodos writeObject/ para controlar con precisión el formato de serialización: si lo hace, puede incluso trabajar con cambios drásticos en la clase.
  3. Utilice JSON/XML o cualquier otro formato de almacenamiento que maneje limpiamente la traducción. Quizás tu mejor apuesta.
Cuestiones relacionadas