¿Cómo puedo compartir una variable u objeto entre dos o más servlets?


39

Me gustaría saber si hay alguna forma de compartir una variable o un objeto entre dos o más Servlets, me refiero a una forma "estándar". Supongo que esta no es una buena práctica, pero es una forma más fácil de construir un prototipo.

no sé si depende de las tecnologías utilizadas, pero voy a utilizar Tomcat 5,5


quiero compartir un vector de objetos de una clase simple (sólo atributos públicos, cuerdas, ints, etc.). Mi intención es tener una información estática como en un DB, obviamente se perderá cuando el Tomcat se detenga. (es solo para Pruebas)

  0

Depende en gran medida del tipo de objeto/variable que sea. ¿La variable pertenece a una clase y solo quieres acceso? ¿Es una constante? Un ejemplo sería bueno. 23 sep. 082008-09-23 20:34:14

  0

Ojalá esto ayude :) 23 sep. 082008-09-23 20:43:24

74

Creo que lo que está buscando aquí es solicitud, sesión o datos de aplicación.

En un servlet se puede añadir un objeto como un atributo de la solicitud objeto, objeto de sesión o contexto servlet objeto:

protected void doGet(HttpServletRequest request, HttpServletResponse response) { 
    String shared = "shared"; 
    request.setAttribute("sharedId", shared); // add to request 
    request.getSession().setAttribute("sharedId", shared); // add to session 
    this.getServletConfig().getServletContext().setAttribute("sharedId", shared); // add to application context 
    request.getRequestDispatcher("/URLofOtherServlet").forward(request, response); 
} 

Si lo coloca en el objeto solicitud que estará disponible para el servlet que se remite a la solicitud hasta que se terminó:

request.getAttribute("sharedId"); 

Si lo pones en la sesión que estará disponible para todos los servlets en el futuro, pero el valor será atada al usuario:

request.getSession().getAttribute("sharedId"); 

Hasta que la sesión caduque en función de la inactividad del usuario.

se restablece por usted:

request.getSession().invalidate(); 

O uno servlet quita de alcance:

request.getSession().removeAttribute("sharedId"); 

Si lo coloca en el contexto de servlet que estarán disponibles mientras se ejecuta la aplicación:

this.getServletConfig().getServletContext().getAttribute("sharedId"); 

hasta que lo quite:

this.getServletConfig().getServletContext().removeAttribute("sharedId"); 
  0

¿Puede extender su respuesta para ServletContext? 23 sep. 082008-09-23 20:57:28

+1

O 'getServletContext()' en lugar de 'this.getServletConfig(). GetServletContext()' ... 10 nov. 152015-11-10 08:55:26

  0

@William ¿Cómo puedo pasar algo más que un String f.e. un objeto de una clase que yo mismo creé? 26 nov. 152015-11-26 08:35:12

  0

@Dongo Seré sincero, ya pasé mucho tiempo desde la última vez que trabajé con servlets, pero si recuerdo correctamente mientras usaba String para el ejemplo, podía ser cualquier objeto. 27 nov. 152015-11-27 17:56:51


1

¿No podría simplemente poner el objeto en la HttpSession y luego referirse a él por su nombre de atributo en cada uno de los servlets?

por ejemplo:

getSession().setAttribute("thing", object); 

... entonces en otro servlet:

Object obj = getSession.getAttribute("thing"); 
  0

no tiene que ser serializable objeto para que esto funcione? 06 sep. 132013-09-06 16:56:04


7

depende del alcance del uso previsto de los datos.

Si los datos sólo se utiliza sobre una base por usuario, como información de acceso del usuario, la página de aciertos, etc utilizan el objeto de sesión (httpServletRequest.getSession(). Get/setAttribute (String [, objeto]))

Si se trata de los mismos datos en varios usuarios (resultados totales de la página web, subprocesos de trabajo, etc.) utilice los atributos de ServletContext. servlet.getServletCongfig(). getServletContext(). get/setAttribute (String [, Object])). Esto solo funcionará dentro del mismo archivo war/aplicación web. Tenga en cuenta que estos datos tampoco se conservan en los reinicios.

  0

Usar ServletContext puede meterlo fácilmente en problemas si no tiene cuidado. Por ejemplo, no podría usarlo para implementar un recuento de aciertos de página de forma ingenua: obtenga el recuento de aciertos de la página actual del contexto, increméntelo y establezca el valor para el contexto. Multi-threading mata esa solución. 23 sep. 082008-09-23 21:06:49

  0

Meta crítica: la pregunta es preguntar por la funcionalidad que un almacén de datos de respaldo debe manejar a través de las transacciones de todos modos. Las quejas sobre ACID deben resultar en el uso de un servicio de datos ACID. ServletContext y Session violan todo ACID de alguna manera. 24 sep. 082008-09-24 19:46:05


8

Ponlo en alguno de los 3 diferentes ámbitos. solicitud

- dura vida de petición

sesión - tiene una duración de vida de la sesión del usuario

aplicación - dura hasta applciation se cierra

Puede acceder a todos estos ámbitos a través de la variable HttpServletRequest que es pasó a los métodos que se extienden desde el HttpServlet class


2

Otra opción, compartir datos entre contextos ...

share-data-between-servlets-on-tomcat

<Context path="/myApp1" docBase="myApp1" crossContext="true"/> 
    <Context path="/myApp2" docBase="myApp2" crossContext="true"/> 

En myApp1:

ServletContext sc = getServletContext(); 
    sc.setAttribute("attribute", "value"); 

En myApp2:

ServletContext sc = getServletContext("/myApp1"); 
    String anwser = (String)sc.getAttribute("attribute"); 

0

Así es como lo hago con embarcadero.

https://stackoverflow.com/a/46968645/1287091

utiliza el contexto del servidor, donde un producto único se escribe durante el inicio de un servidor embarcadero integrado y compartido por todos los webapps para la vida del servidor. También se puede usar para compartir objetos/datos entre webapps, suponiendo que solo haya un escritor en el contexto; de lo contrario, debe tener en cuenta la simultaneidad.