1. Conceptos básicos
El oyente en Javaweb se implementa a través del patrón de diseño del observador. Con respecto al modo Observador, no daré demasiada introducción aquí, por lo que hablaré más o menos sobre lo que significa.
El modo Observer también se llama modo de suscripción Publish o modo de oyente. Hay dos caracteres en este modo: el observador y el observador (generalmente también llamado sujeto). El observador registra un evento de interés en el tema. Cuando ocurra este evento, el tema notificará al observador a través de una interfaz de devolución de llamada.
Déjame darte un ejemplo en la vida: suscribir a los periódicos. Cualquier familia o individuo puede suscribirse a periódicos con el periódico. Aquí el periódico es el "tema" y la familia es el "observador". Por ejemplo, si una familia necesita suscribirse al periódico mañana por la mañana, este es un "evento". A la mañana siguiente, se produjo el periódico, y este fue el "evento". Cuando ocurre el incidente, el periódico envía el periódico al buzón de la casa, que es la "interfaz de devolución de llamada".
Para los oyentes en Javaweb, la especificación de servlet define algunas columnas de clases de interfaz de oyente, exponiendo eventos a la aplicación a través de clases de interfaz. Si una solicitud quiere escuchar eventos de interés, no tiene que registrar directamente el evento correspondiente. En cambio, escribe su propio oyente para implementar la clase de interfaz correspondiente y registra a su propio oyente al contenedor de servlet. Cuando ocurre un evento que le importa el programa, el contenedor de servlet notificará al oyente y volverá a llamar a los métodos en el oyente. El oyente personalizado aquí es el observador, y el contenedor de servlet es el tema.
2. Análisis de muestras
Como se mencionó anteriormente, el contenedor Servlet expone los eventos a la aplicación a través de la clase de interfaz del oyente. Por lo tanto, no se trata tanto de registrar eventos, sino registrar oyentes. Los pasos de programación correspondientes son: 1. Escriba su propio oyente e implementa una interfaz de oyente específica. 2. Registre a su oyente en Web.xml. Aquí hay un ejemplo de la interfaz del oyente más simple ServletContextListener:
1.TestListener.java
public class TestListener implementa ServletContextListener {public testListener () {} public void contextInitialized (servletContextEvent scce) {System.out.println ("ServletContextListener.Contextinitialized");} public void contextDestroyed (servletTextEvent scCeVent) {System.out.println ("ServletContextListener.ContextDestroyed");}}2.Web.xml
<Oyerer> <Oyerer-class> com.nantang.listener.testlistener </secher-class> </oyente>
Cuando se inicia el contenedor, "ServletContextListener.Contextinitialized" se emitirá al registro, y cuando el contenedor esté cerrado, se emitirá "ServletContextListener.ContextDestroyed". Una explicación detallada se analizará más adelante.
Cabe señalar aquí que si demuestra el ejemplo anterior en el IDE (Eclipse, STS, etc.), al iniciar el servidor, puede ver "servletContextListener.contextinitialized" en la consola, y al cerrar el servidor, no puede ver "servletContexstener.contextDestroyed". Esto no es que el método contextable no se ejecute, sino que el IDE no lo está implementando perfectamente. Para verificar que ContextDestroyed se llame de hecho, puede escribir un código en contextyDestrOyed para producir el contenido del archivo en lugar de generarlo a la consola.
3. Análisis del código fuente
Ahora analicemos qué eventos nos define la especificación de servlet para nosotros. Más precisamente, qué interfaces de escucha están definidas. Las siguientes presentaciones se basan en la especificación Servlet 3.0.
Servlet3.0 nos proporciona 8 interfaces de oyentes, que se pueden dividir en tres categorías de acuerdo con su alcance:
1. Interfaces de escucha relacionadas con el contexto de servicio, que incluyen: ServletContextListener y ServletContextAttributeListener.
2. Interfaces de escucha relacionadas con la sesión HTTP, que incluyen: httpsessionListener, httpsessionActivationListener, httpsessionTtributeListener y httpsessionbindingListener.
3. La interfaz de escucha relacionada con la solicitud de servlet, que incluye: ServLetRequestListener y ServLetRequestatTributEnstener.
De hecho, por el nombramiento de la interfaz, debería poder adivinar sus funciones básicas. Vamos a explicarlo por categoría a continuación.
1. Interfaz de escucha relacionada con el contexto de servicio
Al introducir servlets antes, explicamos que una aplicación web corresponde a un contexto de servlet. Por lo tanto, el rango de vida de los eventos escuchados por ServletContextListener y ServletContextAttributeListener se ejecuta a través de toda la aplicación web. A continuación se muestra la relación jerarquía del diagrama de clases entre estas dos interfaces.
1.1 EventListener
EventListener es una interfaz de etiqueta, y todos los oyentes de eventos deben heredar esta interfaz. Esta es la especificación de servlet, y no hay explicación.
1.2 EventObject
Similar a EventListener, EventObject es una clase de nivel de evento, y todas las clases de eventos específicas deben heredar EventObject.
La clase pública EventObject implementa java.io.Serializable {Fuente de objeto transitorio protegido; public EventObject (Fuente de objeto) {if (fuente == null) tirar nueva ilegalArGumentException ("fuente nulo"); this.source = fuente;} public object getSource () {Source de return;} public String toString () {return getClass (). "]";}}Esta clase es muy simple, su esencia es solo una cosa: fuente. A través del nombre de clase EventObject y la fuente de nombre de la propiedad, puede ver que esta clase hace una cosa, manteniendo el "Objeto de origen del evento".
1.3 ServletContextEvent
La clase pública ServletContextEvent extiende java.util.eventObject {public ServletContextEvent (ServletContext Source) {super (fuente);} public ServletContext getServletContext () {return (servletContext) super.getSource ();}}Evento de contexto de Servlet, esta clase de eventos es una simple herencia de EventObject. La instancia de ServletContext se proporciona como la fuente del evento en el constructor. Debido a que la fuente del evento es un contexto de servlet, se proporciona un GetServletContext para obtener la instancia de ServletContext.
Cuando explicamos otras clases de eventos en el futuro, todas son el mismo molde. Cada clase de eventos proporciona el método de construcción correspondiente, pasa en el objeto de origen del evento correspondiente y proporciona métodos adicionales para obtener la fuente de eventos. Por lo tanto, EventObject es la clase base de fuente de eventos. La esencia de todas las subclases de eventos hace una cosa, determine el objeto de origen de eventos específico.
Entonces, el lugar donde explicaremos el incidente más tarde pasa.
1.4 ServletContextListener
Public Interface ServletContextListener extiende EventListener {public void contextInitialized (servletContextEvent sce); public void contextDestroyed (servletContextEvent sce);}La interfaz del oyente del contexto de servlet corresponde a dos eventos: el evento de inicialización de contexto de servlet y el evento de cierre del contexto de servlet.
Cuando se inicializa la aplicación web, el contenedor de servlet construirá la instancia de servicio de servicio y devolverá el método contextinitialize.
Cuando el contexto de servlet está a punto de cerrarse, generalmente antes de cerrar el servidor, el contenedor de servlet construirá la instancia de servicio de servicio y devolverá el método contextedestroyed. Cabe señalar aquí que la ejecución del método contextable -desestimado se realizará después de que todos los servlets y los filtros hayan completado el método Destroy.
Entonces, si queremos hacer algo cuando la aplicación comience o se cierre, escribiremos a nuestro propio oyente para implementar la interfaz.
Todos los oyentes de eventos también son el mismo modelo. El método de interfaz de devolución de llamada de evento correspondiente se define de acuerdo con la especificación de servlet. El parámetro de entrada del método es la instancia de origen del evento correspondiente. Por lo tanto, también pasaremos por el lugar donde explicaremos el monitor más adelante.
1.5 ServletContextAttributeEvent
public class ServletContextAtTruteeVent extiende ServletContextEvent {private String Name; private Object Value; public ServletContextAtTributeEvent (ServletContext Source, String Name, Object Value) {super (fuente); this.name = name; this.value = value;} public String getName () {return this.name;} public Object getValue () }}ServletContextAttributeEvent representa un evento relacionado con el atributo de contexto de servlet. En general, el evento se activará cuando cambie el atributo. Esta clase hereda ServletContextEven, y la fuente del evento también es una instancia de ServletContext. Se proporcionan métodos adicionales para obtener nombres de atributos y valores de atributos.
1.6 ServletContextAttributeListener
La interfaz pública ServletContextAttributeEnstener extiende EventListener {public void atributeadDed (servletContextatTributeEvent scAb); public void atributereMoved (ServletContextatTributeEvent SCAB); public void atributeRePlaced (ServletContextAttributeeVevent Scab);}Cuando los atributos anteriores del servlet se agregan, eliminan o modifican, el contenedor de servlet construye el objeto de evento ServletContextAttributeeVent, y devuelve los métodos atributados, atributerementados y aplicados a los atribuidos respectivamente.
Lo que debe tener en cuenta aquí es el método AttribuTeRepliced, que devuelve cuando se reemplaza el valor del atributo. En este momento, si llama al método ServletContextAttributeeVent.getValue (), la devolución es reemplazar el valor de atributo anterior.
2 interfaz de escucha relacionada con la sesión HTTP
2.1 httpsessionevent
clase pública httpSessionEvent extiende java.util.eventObject {public httpSessionEvent (httpsession fuente) {super (fuente);} public httpsession getSession () {return (httpsession) super.getSource ();}}Evento relacionado con la sesión HTTP, que se activará cuando cambie la sesión. La fuente del evento es una instancia de httpsession y proporciona métodos adicionales de adquisición de httpsession.
2.2 httpsessionListener
interfaz pública httpsessionListener extiende EventListener {public void session created (httpsessionEvent se); public void sessionDestrOyed (httpsessionEvent se);}Cuando se crea y destruye la sesión, el contenedor de servlet construye el objeto de evento HttpsessionEvent y devuelve los métodos de session created y sessionDestrOyed.
2.3 httpsessionActivationListener
interfaz pública httpsessionActivationListener extiende EventListener {public void sessionwillpassivate (httpsessionEvent se); Public void sessionDidActivate (httpsessionEvent se);}Cuando la sesión está a punto de ser pasivada o ha sido activada, el contenedor Servlet construye el objeto de evento HttpSessionEvent, la devolución de llamada SessionSpassivate y los métodos de SessionDidActivate.
La pasivación y la activación se explican aquí: la pasivación se refiere a la memoria del servidor es insuficiente o el tiempo de espera de actividad de la sesión ha llegado, y la sesión inactiva recientemente se está serializada en el disco. La activación significa que se accede nuevamente a una sesión pasiva, deserializando la sesión de disco a memoria.
Se puede ver aquí que para pasivarse y activarse, la sesión debe ser serializada y deserializada primero. Al mismo tiempo, durante el proceso de programación, intentamos usar objetos simples como String e Integer tanto como sea posible, e intentamos no usar colecciones como Lista y Mapa.
2.4 httpsessionbindingevent
clase pública httpSessionBindingEvent extiende httpSessionEvent {private String Name; private Object Value; public httpSessionBindingEvent (httpsession session, name de cadena) {super (session); this.name = name;} public httpSessionBinDingEvent (httpsession Session, nombre de cadena, valor de objeto) {super (session); this.name = name; valor;} public httpsession getSession () {return super.getSession ();} public String getName () {return name;} public object getValue () {return this.value; }}El evento relacionado con el atributo de sesión HTTP se activa cuando cambia el atributo de sesión. La fuente del evento es una instancia de httpsession y proporciona métodos adicionales para obtener httpsession, nombre de atributo y valor de atributo.
2.5 httpsessionAttributelistener
interfaz pública httpSessionAtTributEnstener extiende EventListener {public void atributeadded (httpsessionbindingeVent se); public atributereremoved (httpsessionbindingEvent se); public void atributeRePlaced (httpsessionbindingeVent se);}Cuando se agrega, elimina o modifica el atributo de sesión, el contenedor de servlet construye el objeto de evento httpsessionbindingEvent y devuelve los métodos AttributeDDed, AttributeRemed y AttribuTePralled, respectivamente.
Lo que debe tener en cuenta aquí es el método AttribuTeRepliced, que devuelve cuando se reemplaza el valor del atributo. En este momento, si llama al método ServletContextAttributeeVent.getValue (), la devolución es reemplazar el valor de atributo anterior.
Cuando se llama el método de invalidar de la sesión o la sesión falla, el método AttribuTerEmed también se volverá a llamar.
2.6 httpsessionbindinglistener
interfaz pública httpsessionbindingListener extiende EventListener {public Void ValueBound (httpsessionbindingEvent Event); public void ValueUnBound (httpsessionbindingEvent Event);}Este oyente también escucha cambios en el atributo de la sesión. Cuando se agrega y elimina el atributo de la sesión, es decir, cuando el valor del atributo está obligado y el valor del atributo no está nacido, el contenedor Servlet construye el objeto de evento HttpSessionBindingEvent y devuelve los métodos ValueBound y ValueUnbound respectivamente.
No se ve diferente de httpsessionAttributeListener, pero no es el caso. Una diferencia esencial entre los dos es la condición de activación del evento.
Cuando hay algún cambio en la propiedad de la sesión, el contenedor de servlet notificará al httpsessionAttributeListener. Pero para httpsessionbindingListener, el contenedor de servlet notificará solo si el valor de la propiedad limitado o sin distorsión es una instancia del oyente. Por ejemplo:
Public Class TestListener implementa httpsessionBindingListener {@OverridePublic Void ValueBound (httpSessionBindEnsevent Event) {System.out.println ("httpsessionbindingListener.valueBound");}@overDidPoid ValueunBound (httPsessionBindingEvent Event) {System.out.println ("httpsessionbindingListener.valueunBound");}}Personalizamos el oyente TestListener para implementar httpsessionbindinglistener. Establezcamos el siguiente atributo de sesión en el código:
Httpsession session = request.getSession (); testListener testListener = new testListener (); session.SetAttribute ("oyente", testListener); session.removeattribute ("oyente");Aquí el valor de atributo de la sesión es nuestra instancia de TestListener de oyente. Entonces, cuando se ejecute este código, el contenedor Servlet notificará al TestListener y devuelve los métodos ValueBound y ValueUnBound.
Cabe señalar aquí que cuando se llama el método de invalidar de la sesión o la sesión falla, el método ValueUnBound también se volverá a llamar.
3 interfaz de escucha relacionada con la solicitud de servlet
3.1 ServLetRequestevent
public class ServLetRequestEvent extiende java.util.eventObject {private ServLetRequest solicitud; public ServLetRequestEvent (ServletContext sc, ServletRequest request) {super (sc); this.request = request;} public servletRest GetServletRequest () {return this.Request;} public ServletContextContext () {) {) (ServletContext) super.getSource ();}}El evento relacionado con la solicitud de servlet se activará cuando cambie la solicitud. La fuente del evento es una instancia de ServletContext y proporciona una obtención adicional de los métodos de ServletContext y ServLetRequest.
3.2 ServLetRequestListener
Interfaz pública ServLetRequestListener extiende EventListener {public void requestDestroyed (ServLetRequestEvent SRE); Public void requestInitialized (ServLetRequestEvent SRE);}Cuando la solicitud se inicializa o destruye, el cliente solicita ingresar la aplicación web (ingrese el servlet o el primer filtro) o la aplicación web devuelve una respuesta al cliente (salga del servlet o el primer filtro). El contenedor de servlet construye la instancia de ServLetRequestEvent y devuelve los métodos requestsinitializados y de requisito.
3.3 ServLetReCestAtTributeEvent
clase pública ServletRequestAtTributeeVent EXTENDS SERVELTREQUESTEVENT {private String Name; private Object Value; public ServLetRequestAtTributeEvent (servletContext sc, servletRequest request, string name, valor de objeto) {super (sc, request); this.name = name; this.value = valor;} public string string getName () {return this.name;} este valor; }}El evento relacionado con el servlet solicita el atributo, que se activará cuando cambie el atributo de solicitud. La fuente del evento es una instancia de ServletContext y proporciona métodos adicionales para obtener nombres de atributos y valores de atributos.
3.4 SERVLETREQUESTTURIBELISTENER
Interfaz pública ServLetRequestAtTributEnstener extiende EventListener {public void atributeadDed (servletRequestatTributeeVent Srae); public void atributereMoved (servletRequestTtributeEvent Srae); public void atributeRePlaced (servletRequestTtributeEventEvent Srae);}Cuando se agregan, eliminan o modifican los atributos solicitados, el contenedor de servlet construye el objeto de evento ServLetRequestatTributeEvent, y vuelva a llamar a los métodos atributados, atributerements y se aplican a los atribuidos respectivamente.
Lo que debe tener en cuenta aquí es el método AttribuTeRepliced, que devuelve cuando se reemplaza el valor del atributo. En este momento, si llama al método ServLetRequestAtTribiTEEVEvent.getValue (), la devolución es reemplazar el valor de atributo anterior.
4. Resumen
En este punto, el oyente terminó de hablar. Podemos encontrar que el oyente, el servlet y el filtro tienen una cosa en común, ambos están programados por contenedores. Solo necesitamos escribir nuestro propio oyente para implementar la interfaz del oyente que nos preocupamos y registrarnos. El resto del trabajo es escribir una lógica comercial en nuestro propio oyente.
El oyente introducido en esta publicación de blog está formulado por la especificación Servlet 3.0. 3.1 ha agregado algunas interfaces de oyentes de eventos, y los principios son similares, los lectores pueden entenderlas por sí mismos.