1. Conceitos básicos
O ouvinte em Javaweb é implementado através do padrão de design do observador. Em relação ao modo de observador, não vou dar muita introdução aqui, então vou falar aproximadamente sobre o que isso significa.
O modo Observador também é chamado de modo de assinatura de publicação ou modo de ouvinte. Existem dois caracteres nesse modo: o observador e o observador (geralmente também chamados de sujeito). O Observer registra um evento de interesse no tópico. Quando este evento ocorre, o tópico notificará o observador por meio de uma interface de retorno de chamada.
Deixe -me dar um exemplo na vida: assine os jornais. Qualquer família ou indivíduo pode se inscrever em jornais com o jornal. Aqui, o jornal é o "tema" e a família é o "Observer". Por exemplo, se uma família precisa se inscrever no jornal amanhã de manhã, este é um "evento". Na manhã seguinte, o jornal foi produzido, e este foi o "evento". Quando o incidente ocorre, o jornal envia o jornal para a caixa de correio domiciliar, que é a "interface de retorno de chamada".
Para os ouvintes em Javaweb, a especificação do servlet define algumas colunas de classes de interface do ouvinte, expondo eventos ao aplicativo por meio de classes de interface. Se um aplicativo deseja ouvir eventos de interesse, ele não precisará registrar diretamente o evento correspondente. Em vez disso, ele escreve seu próprio ouvinte para implementar a classe de interface correspondente e registra seu próprio ouvinte no contêiner do servlet. Quando um evento com o qual o programa se preocupa, o contêiner de servlet notificará o ouvinte e chama de volta os métodos no ouvinte. O ouvinte personalizado aqui é o observador e o contêiner de servlet é o tema.
2. Análise de amostra
Como mencionado acima, o contêiner do servlet expõe eventos ao aplicativo através da classe de interface do ouvinte. Portanto, não somos tanto em registrar eventos, mas registrar ouvintes. As etapas de programação correspondentes são: 1. Escreva seu próprio ouvinte e implemente uma interface específica do ouvinte. 2. Registre seu ouvinte em web.xml. Aqui está um exemplo da interface mais simples do ouvinte ServletContextListener:
1.TestListener.java
public class Testlistener implementa servletContextListener {public testListener () {} public void contextinitialized (servletContextevent scce) {System.out.println ("servletContextListener.Contextinitialized");} vazio público contextDestroyled (servletLextextextexten. {System.out.println ("ServletContextListener.ContextDestroyed");}}2.Web.xml
<Ilanter> <lister-class> com.nantang.listener.testlistener </lister-class> </lister>
Quando o contêiner é iniciado, "ServletContextListener.Contextinitialized" será emitido para o log e quando o contêiner estiver fechado ", será a saída" ServletContextListener.ContextDestroyed "será a saída. Uma explicação detalhada será analisada posteriormente posteriormente.
Deve -se notar aqui que, se você demonstrar o exemplo acima no IDE (Eclipse, STs etc.), ao iniciar o servidor, poderá ver "ServletContextListener.Contextinitialized" no console e, ao fechar o servidor, você não pode ver "ServletContextListener.ContetDestroyled". Isso não é que o método do contextDestroyed não seja executado, mas que o IDE não o implemente perfeitamente. Para verificar se o ContextDestroyed é realmente chamado, você pode escrever uma parte do código no contextDestroyed para produzir o conteúdo do arquivo em vez de emitá -lo para o console.
3. Análise do código -fonte
Agora vamos analisar quais eventos a especificação do servlet define para nós. Mais precisamente, quais interfaces de escuta são definidas. As apresentações a seguir são baseadas na especificação Servlet 3.0.
Servlet3.0 nos fornece 8 interfaces de ouvinte, que podem ser divididas em três categorias de acordo com seu escopo:
1.Servlet Interfaces de escuta relacionadas ao contexto, incluindo: ServletContextListener e ServletContextTtributelistener.
2. Interfaces de escuta relacionadas à sessão HTTP, incluindo: HTTPSessionListener, HttpSessionActivationListener, HttpSessionAttributelistener e HttpSessionBindingListener.
3. A interface de escuta relacionada à solicitação do servlet, incluindo: servletRequestListener e servletRequestattributelistener.
De fato, pela nomeação da interface, você poderá adivinhar suas funções básicas. Vamos explicar por categoria abaixo.
1. Interface de escuta relacionada ao contexto
Ao introduzir servlets antes, explicamos que um aplicativo da Web corresponde a um contexto de servlet. Portanto, a gama de eventos de vida ouvida por ServletContextListener e ServletContextTtributelistener percorre todo o aplicativo da web. Abaixo está a relação hierarquia do diagrama de classes entre essas duas interfaces.
1.1 EventListener
EventListener é uma interface de tag e todos os ouvintes de eventos devem herdar essa interface. Esta é a especificação do servlet e não há explicação.
1.2 EventObject
Semelhante ao EventListener, o EventObject é uma classe no nível do evento, e todas as classes de eventos específicas devem herdar o EventObject.
classe pública EventObject implementa java.io.Serializable {fonte de objeto transitório protegido; public EventObject (Object Source) {if (fonte == null) lançar novo ilegalArgumentException ("fonte nula"); th) string (strorn) (} Return (} public objeto getSource () {return; "]";}}Esta classe é muito simples, sua essência é apenas uma coisa: fonte. Através do nome da classe EventoObject e da fonte do nome da propriedade, você pode ver que essa classe faz uma coisa, segurando o "Objeto de origem do evento".
1.3 ServletContextevent
classe pública servletContextevent estende java.util.EventoBject {public servletContextevent (servletContext fonte) {super (fonte);} public servletContext getServletContext () {return (servletContext) super.getsource ();}}}}Evento de contexto de servlet, esta classe de eventos é uma herança simples do EventObject. A instância do servletContext é fornecida como fonte de evento no construtor. Como a fonte do evento é um contexto de servlet, é fornecido um getServletContext para obter a instância do servletContext.
Quando explicamos outras aulas de eventos no futuro, elas são todas as mesmas moldes. Cada classe de evento fornece o método de construção correspondente, passa no objeto de origem do evento correspondente e fornece métodos adicionais para obter a fonte do evento. Portanto, o EventObject é a classe base da fonte de evento. A essência de todas as subclasses de eventos faz uma coisa, determine o objeto de fonte de evento específico.
Portanto, o lugar onde explicaremos o incidente passa posteriormente.
1.4 ServletContextListener
interface pública servletContextListener estende o evento {public void contextinitialized (servletContextevent sce); public void contextDestroyed (servletContextevent sce);}A interface do ouvinte de contexto de servlet corresponde a dois eventos: o evento de inicialização do contexto do servlet e o evento de fechamento do contexto do servlet.
Quando o aplicativo da Web for inicializado, o contêiner do servlet construirá a instância do servletContexteven e retornará o método Contextinitialize.
Quando o contexto do servlet está prestes a ser fechado, geralmente antes de fechar o servidor, o contêiner do servlet construirá a instância do servletContexteven e retornará o método ContextDestroyed. Deve -se notar aqui que a execução do método contextDestroyed será realizada depois que todos os servlets e filtros concluírem o método de destruição.
Portanto, se quisermos fazer algo quando o aplicativo iniciar ou fechar, escreveremos nosso próprio ouvinte para implementar a interface.
Todos os ouvintes de eventos também são o mesmo modelo. O método de interface de retorno de chamada de evento correspondente é definido de acordo com a especificação do servlet. O parâmetro de entrada do método é a instância da fonte de evento correspondente. Portanto, também passaremos pelo local onde explicaremos o monitor posteriormente.
1.5 ServletContextTtributEEvent
classe pública serverletContextTtributerEvent estende o servletContexTevent {nome da sequência privada; valor do objeto privado; public servletContextTtructributeEvent (fonte servletContext, nome da string, valor do objeto) {super (fonte); this.name = name; this.value = value;} public string getName () {return.Name; }}ServletContextTtributerEvent representa um evento relacionado ao atributo de contexto do servlet. Geralmente, o evento será acionado quando o atributo mudar. Esta classe herda o servletContexteven, e a fonte do evento também é uma instância do servletContext. Métodos adicionais para obter nomes de atributos e valores de atributo são fornecidos.
1.6 ServletContextTtributElistener
interface pública servletContextTatributElistener estende o EventListener {public void atributeAdded (scab do servletContextTtributerEvent); public void atribuiReemoved (servletContextTributeevent Scab); vazio público atribuído (servletContexttributerEvent Scab);}Quando os atributos acima do servlet são adicionados, excluídos ou modificados, o contêiner do servlet constrói o objeto ServletContextTributerEvent de eventos e chama os métodos atribuídos atribuídos, atribuidos e atribuídos, respectivamente.
O que você precisa observar aqui é o método AttributeReplaced, que liga de volta quando o valor do atributo é substituído. No momento, se você ligar para o método ServletContextTtributerEvent.getValue (), o retorno será substituir o valor do atributo anterior.
2 interface de escuta relacionada à sessão HTTP
2.1 HttpSessionEvent
classe pública httpSessionEvent estende java.util.EventoBject {public httpSessionEvent (httpSession Source) {super (fonte);} public httpSession getSession () {return (httpsession) super.getSource ();}}Evento relacionado à sessão HTTP, que será acionado quando a sessão mudar. A fonte do evento é uma instância de HTTPSession e fornece métodos adicionais de aquisição de HTTPSession.
2.2 HttpSessionListener
interface pública httpsessionlistener estende o evento de evento {public void sessionCreated (httpsessionEvent SE); public void sessionDestroyed (httpsessionEvent SE);}Quando a sessão é criada e destruída, o contêiner do servlet constrói o objeto de evento HTTPSessionEvent e chama os métodos SessionCreated e SessionDestroyed.
2.3 HttpSessionActivationListener
interface pública httpSessionActivationListener estende o EventListener {public void sessionwillpassivate (httpsessionEvent SE); public void sessionDidActivate (httpsessionEvent SE);}Quando a sessão está prestes a ser passivada ou foi ativada, o contêiner servlet constrói o objeto de evento HTTPSessionEvent, os métodos de retorno de chamada de retorno de retorno e sessões e sessões.
A passivação e a ativação são explicadas aqui: a passivação refere -se à memória do servidor é insuficiente ou o tempo limite da atividade da sessão chegou, e a sessão recentemente inativa é serializada para o disco. A ativação significa que uma sessão passiva é acessada novamente, desaperiando a sessão do disco para a memória.
Pode -se ver aqui que, para passivar e ativar, a sessão deve ser serializada e desserializada primeiro. Ao mesmo tempo, durante o processo de programação, tentamos usar objetos simples, como string e número inteiro, tanto quanto possível, e tentamos não usar coleções como LIST e MAP.
2.4 HttpSessionBindingEvent
classe pública httpSessionBindingEvent estende httpSessionEvent {Nome da sequência privada; valor do objeto privado; public httpSessionBindingEvent (sessão httpSession, nome da string) {super (session); this.name = name;} public httpSessionBindBindEvent (httpSession session, string; Nome; objeto; HttpSession getSession () {return super.getSession ();} public string getName () {return name;} public object getValue () {return this.value; }}O evento relacionado ao atributo de sessão HTTP é acionado quando o atributo da sessão mudar. A fonte do evento é uma instância de HTTPSession e fornece métodos adicionais para obter httpsession, nome de atributo e valor de atributo.
2.5 HttpSessionAttributelistener
interface pública httpSessionAttributelistener estende o evento de eventListener {public void atribuiDedded (httpSessionBindingEvent SE); public void atribuiReemoved (httpSessionBindingEvent se); public void atribui (httpsessionbindingingEvent se);}Quando o atributo da sessão é adicionado, excluído ou modificado, o contêiner do servlet constrói o objeto de evento HttpSessionBindingEvent e chama os métodos atribuídos atribuídos, atribuiados e atribuídos, respectivamente.
O que você precisa observar aqui é o método AttributeReplaced, que liga de volta quando o valor do atributo é substituído. No momento, se você ligar para o método ServletContextTtributerEvent.getValue (), o retorno será substituir o valor do atributo anterior.
Quando o método invalidado da sessão é chamado ou a sessão falha, o método atribuiário também será chamado de volta.
2.6 HttpSessionBindingListener
interface pública httpSessionBindingListener estende o EventListener {public void ValueBound (evento httpSessionBindingEvent); public void valueunbound (evento httpSessionBindingEvent);}Esse ouvinte também ouve alterações no atributo da sessão. Quando o atributo da sessão é adicionado e excluído, ou seja, quando o valor do atributo é vinculado e o valor do atributo não é finalizado, o contêiner servente constrói o objeto de evento HTTPessionBindingEvent e chama os métodos ValueBound e ValueUnbound, respectivamente.
Não parece diferente do httpSessionAttributelistener, mas não é o caso. Uma diferença essencial entre os dois é a condição de acionamento do evento.
Quando houver alguma alteração na propriedade da sessão, o contêiner do servlet notificará o httpSessionAttributelistener. Mas, para o HTTPSessionBindingListener, o contêiner servente notificará apenas se o valor da propriedade ligado ou sem fiscalização for uma instância do ouvinte. Por exemplo:
Public Class TestListener implementa httpSessionBindingListener {@OverridePublic void ValueBound (httpSessionBindingEvent Event) {System.out.println ("httpSessionBindingListener.valuBound");}@expedrideIrditublic ValueUnbound (HTTPSPSP (httpSpSpSion "); {System.out.println ("httpSessionBindingListener.valueUnbound");}}Personalizamos o Listener Testlistener para implementar o HTTPSESSESSÃOBINDINGLISTENER. Vamos definir o atributo da sessão a seguir no código:
HTTPSession Session = request.getSession (); testListener testListener = new Testlistener (); session.setAttribute ("ouvinte", testListener); session.removeattribute ("ouvinte");Aqui, o valor do atributo da sessão é a nossa instância do Listener Testlistener. Portanto, quando esse código for executado, o contêiner do servlet notificará o TestListener e liga de volta os métodos ValueBound e ValueUnbound.
Deve -se notar aqui que, quando o método invalidado da sessão for chamado ou a sessão falha, o método ValueUnbound também será chamado de volta.
3 interface de escuta relacionada à solicitação de servlet
3.1 ServletRequestevent
classe pública servletRequestevent estende java.util.EventoBject {Private servletRequest Request; public servletRequestevent (servletContext sc, servletRequest request) {super (sc); this.request = request;} public servEstleTleTeTExxT () {ret.Request; (ServletContext) super.getSource ();}}O evento relacionado à solicitação do servlet será acionado quando a solicitação for alterada. A fonte do evento é uma instância do servletContext e fornece busca adicional dos métodos ServletContext e ServletRequest.
3.2 ServletRequestListener
interface pública servletRequestListener estende o evento de evento {public void requestDestroyed (servletRequestevent sre); public void requestinitialized (servletRequestevent sre);}Quando a solicitação é inicializada ou destruída, o cliente solicita inserir o aplicativo da web (insira o servlet ou o primeiro filtro) ou o aplicativo da web retorna uma resposta ao cliente (saia do servlet ou do primeiro filtro). O contêiner do servlet constrói a instância do servletRequestevent e chama os métodos RequestInitialized e RequestDestroyed.
3.3 ServletRequestattributeEvent
classe pública servletRequestAttributerEvent estende servletRequestevent {nome da string privada; valor do objeto privado; public servletRequestAttributerEvent (servletContext sc, servletRequest request, nome de string, valor de objeto) {super (sc, solicitação); this.name = this.v.value = value;} string; this.value; }}O evento relacionado ao servlet solicita o atributo, que será acionado quando o atributo de solicitação for alterado. A fonte do evento é uma instância do servletContext e fornece métodos adicionais para obter nomes de atributos e valores de atributo.
3.4 ServletRequestattributElistener
interface pública servletRequestattributElistener estende o evento de eventListener {public void atribuiDedded (servletRequestatbributeevent srae); public void atribuiousoved (servletRequestattributeevent srae); atribuições públicas do vazio (servleTequesttredeventevent Srae);}Quando os atributos solicitados são adicionados, excluídos ou modificados, o contêiner do servlet constrói o objeto de evento servletRequestattributerEvent e ligue de volta os métodos atribuídos atribuídos, atribuidos e atribuídos, respectivamente.
O que você precisa observar aqui é o método AttributeReplaced, que liga de volta quando o valor do atributo é substituído. No momento, se você ligar para o método ServletReQuestAttributerEvent.getValue (), o retorno será substituir o valor do atributo anterior.
4. Resumo
Neste ponto, o ouvinte terminou de falar. Podemos descobrir que o ouvinte, o servlet e o filtro têm uma coisa em comum, ambos são agendados por contêineres. Só precisamos escrever nosso próprio ouvinte para implementar a interface do ouvinte que nos preocupamos e nos registramos. O restante do trabalho é escrever a lógica de negócios em nosso próprio ouvinte.
O ouvinte introduzido nesta postagem do blog é formulado pela especificação Servlet 3.0. 3.1 adicionou algumas interfaces do ouvinte de eventos, e os princípios são semelhantes, os leitores podem entendê -los sozinhos.