Heim  >  Artikel  >  Java  >  Eine detaillierte Einführung in Filter, Servlet und Listener in Java

Eine detaillierte Einführung in Filter, Servlet und Listener in Java

黄舟
黄舟Original
2017-07-30 13:18:361406Durchsuche

Dieser Artikel stellt hauptsächlich die Lernmaterialien von Filter, Servlet und Listener im Detail vor. Ich hoffe, Sie haben einen gewissen Referenzwert Gefällt mir

1. Filterfunktion


Die Filterfunktion ermöglicht es Benutzern, eine Anfrage zu ändern und eine Antwort zu ändern. Filter ist kein Servlet, es kann nicht generiert werden Eine Antwort kann eine Anfrage vorverarbeiten, bevor sie das Servlet erreicht, und sie kann die Antwort auch verarbeiten, wenn sie das Servlet verlässt. Mit anderen Worten, der Filter ist tatsächlich eine „Servlet-Kette“ (Servlet-Kette).


Ein Filter umfasst:


1), Abfangen, bevor das Servlet aufgerufen wird;

2), Überprüfen der Servlet-Anfrage, bevor das Servlet aufgerufen wird;

3), basierend auf Bedarf um den Anforderungsheader und die Anforderungsdaten zu ändern;
4), um den Antwortheader und die Antwortdaten nach Bedarf zu ändern


Der Server Ruft die Methode „setFilterConfig“ nur einmal für die Verarbeitung auf. Die Methode „doFilter“ wird mehrmals aufgerufen, um verschiedene Anforderungen zu verarbeiten. Der Server kann „FilterConfig“ auf „leer“ setzen dass der Filter beendet wurde.
Jeder Filter erhält die aktuelle Anfrage und Antwort von der doFilter()-Methode. In dieser Methode kann jede Operation für die Anfrage und Antwort ausgeführt werden (einschließlich Sammeln von Daten, Packen von Daten usw.). Der Filter ruft chain.doFilter auf ()-Methode übergibt die Kontrolle an den nächsten Filter. Wenn ein Filter die Anforderungsverarbeitung stoppen und die vollständige Kontrolle über die Antwort erlangen möchte, muss er nicht den nächsten Filter aufrufen.

Beispiel:

Erstellen Sie zunächst einen neuen Filter




Konfigurieren Sie ihn in web.xml

/** 
 * 
 */ 
package com.ee.filter; 
 
import java.io.IOException; 
 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
 
/** 
 * @author Administrator 
 * 
 */ 
public class LogFilter implements Filter { 
 private FilterConfig filterConfig; 
 
 public FilterConfig getFilterConfig() { 
  System.err.println("...getFilterConfig..."); 
  return filterConfig; 
 } 
 
 public void setFilterConfig(FilterConfig filterConfig) { 
  System.err.println("...setFilterConfig..."); 
  this.filterConfig = filterConfig; 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.Filter#destroy() 
  */ 
 @Override 
 public void destroy() { 
  System.err.println("...filter destroy..."); 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) 
  */ 
 @Override 
 public void doFilter(ServletRequest request, ServletResponse response, 
   FilterChain chain) throws IOException, ServletException { 
  System.err.println("...doFilter..."); 
  chain.doFilter(request, response);//看到这没,这只要是传递下一个Filter 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) 
  */ 
 @Override 
 public void init(FilterConfig filterConfig) throws ServletException { 
  System.err.println("...init Filter..."); 
  this.filterConfig = filterConfig; 
 } 
 
}



Starten und ausführen
<filter> 
 <filter-name>LogFilter</filter-name> 
 <filter-class>com.ee.filter.LogFilter</filter-class> 
</filter> 
 
<filter-mapping> 
 <filter-name>LogFilter</filter-name> 
 <url-pattern>/*</url-pattern> 
</filter-mapping>

Sie können sehen, dass...init Filter... beim Start von TOMCAT zum ersten Mal gedruckt wird, und dann können Sie...doFilter... sehen gedruckt.

2. Servlet-Funktion


1). Was ist ein Servlet?

Servlet ist ein Java-Programm, das die Java Servlet-Anwendungsprogrammierschnittstelle (API) und verwandte Klassen und Methoden verwendet. Zusätzlich zur Java-Servlet-API können Servlets auch Java-Klassenpakete verwenden, die die API erweitern und ergänzen. Servlets werden auf einem Java-fähigen Webserver oder Anwendungsserver ausgeführt und erweitern die Funktionen dieses Servers. Java-Servlets sind für Webserver das, was Java-Applets für Webbrowser sind. Servlets werden in den Webserver geladen und dort ausgeführt, während Applets in den Webbrowser geladen und dort ausgeführt werden. Die Java-Servlet-API definiert eine Standardschnittstelle zwischen einem Servlet und einem Java-fähigen Server, wodurch Servlets zu einer serverübergreifenden Plattform werden.

Servlets erweitern die Fähigkeiten eines Servers, indem sie ein Framework zur Bereitstellung von Anforderungs- und Antwortdiensten im Web erstellen. Wenn ein Client eine Anfrage an den Server sendet, kann der Server die Anfrageinformationen an das Servlet senden und das Servlet die Antwort erstellen lassen, die der Server an den Client zurückgibt. Servlets können automatisch geladen werden, wenn ein Webserver gestartet wird oder wenn ein Client zum ersten Mal einen Dienst anfordert. Nach dem Laden läuft das Servlet weiter, bis andere Clients Anfragen stellen. Servlets haben ein breites Funktionsspektrum. Beispielsweise kann Servlet die folgenden Funktionen ausführen:

  (1) Erstellen und Zurückgeben einer vollständigen HTML-Seite mit dynamischen Inhalten basierend auf der Art der Kundenanfrage.
 (2) Erstellen Sie einen Teil einer HTML-Seite (HTML-Fragment), der in eine vorhandene HTML-Seite eingebettet werden kann.

 (3) Kommunizieren Sie mit anderen Serverressourcen (einschließlich Datenbanken und Java-basierten Anwendungen).

 (4) Verwenden Sie mehrere Clients, um Verbindungen zu verwalten, Eingaben von mehreren Clients zu empfangen und die Ergebnisse an mehrere Clients zu senden. Ein Servlet könnte beispielsweise ein Spieleserver mit mehreren Teilnehmern sein.
 (5) Wenn die Datenübertragung im Einzelverbindungsmodus zulässig ist, öffnen Sie eine neue Verbindung vom Server zum Applet im Browser und halten Sie die Verbindung
offen. Applets können auch Verbindungen zwischen dem Browser des Clients und dem Server initiieren, sodass Client und Server Sitzungen einfach und effizient durchführen können. Die Kommunikation kann über benutzerdefinierte Protokolle oder Standards wie IIOP erfolgen.
 (6) Verwenden Sie MIME-Typ-Filterdaten für spezielle Verarbeitung, wie z. B. Bildkonvertierung und serverseitige Einbindungen (SSI).
 (7) Eine Standardroutine, die allen Servern eine individuelle Verarbeitung ermöglicht. Beispielsweise kann ein Servlet die Art und Weise ändern, wie Benutzer authentifiziert werden.


2). Der Lebenszyklus eines Servlets
Der Lebenszyklus eines Servlets beginnt, wenn es in den Speicher des Webservers geladen wird, und endet, wenn das Servlet beendet oder neu geladen wird.


(1) Initialisierung
Laden Sie das Servlet zu folgenden Zeiten:

Wenn die Autoload-Option konfiguriert wurde, wird es beim Starten des Servers automatisch geladen

Nach dem Server startet, wenn der Client zum ersten Mal eine Anfrage an das Servlet stellt
Beim Neuladen des Servlets Nach dem Laden des Servlets erstellt der Server eine Servlet-Instanz und ruft die init()-Methode des Servlets auf. Während der Initialisierungsphase werden Servlet-Initialisierungsparameter an das Servlet-Konfigurationsobjekt übergeben.

(2) Anforderungsverarbeitung
Für eine Client-Anfrage, die beim Server eintrifft, erstellt der Server ein „Anfrage“-Objekt und ein „Antwort“-Objekt, das für die Anfrage spezifisch ist. Der Server ruft die service()-Methode des Servlets auf, mit der die Objekte „request“ und „response“ übergeben werden. Die Methode service() ruft die Anforderungsinformationen vom Objekt „request“ ab, verarbeitet die Anforderung und verwendet die Methoden des Objekts „response“, um die Antwort an den Client zurückzuleiten. Die Methode service() kann andere Methoden aufrufen, um die Anforderung zu verarbeiten, z. B. doGet(), doPost() oder andere Methoden.

(3) Beendigung
Wenn der Server das Servlet nicht mehr benötigt oder eine neue Instanz des Servlets neu lädt, ruft der Server die destroy()-Methode des Servlets auf.

3). Java Servlet API
Das Java Servlet Development Tool (JSDK) stellt mehrere Softwarepakete bereit, die beim Schreiben von Servlets benötigt werden. Dazu gehören zwei Basispakete für alle Servlets: javax.servlet und javax.servlet.http. Die Java-Servlet-Entwicklungstools können von der Sun-Website heruntergeladen werden. Im Folgenden wird hauptsächlich die von javax.servlet.http bereitgestellte HTTP-Servlet-Anwendungsprogrammierschnittstelle vorgestellt.
HTTP Servlet verwendet ein HTML-Formular zum Senden und Empfangen von Daten. Um ein HTTP-Servlet zu erstellen, erweitern Sie die HttpServlet-Klasse, eine Unterklasse von GenericServlet, die spezielle Methoden zur Verarbeitung von HTML-Tabellen verwendet. HTML-Formulare werden durch die Tags 632555444b46edf0af44e58213a0ac8c definiert. Formulare enthalten normalerweise Eingabefelder (z. B. Texteingabefelder, Kontrollkästchen, Optionsfelder und Auswahllisten) und Schaltflächen zum Senden von Daten. Bei der Übermittlung von Informationen geben sie auch an, welches Servlet (oder anderes Programm) der Server ausführen soll. Die HttpServlet-Klasse umfasst init(), destroy(), service() und andere Methoden. Die Methoden init() und destroy() werden vererbt.

(1) init()-Methode

 Im Lebenszyklus des Servlets wird die init()-Methode nur einmal ausgeführt. Es wird ausgeführt, wenn der Server das Servlet lädt. Sie können den Server so konfigurieren, dass er ein Servlet lädt, wenn er gestartet wird oder wenn ein Client zum ersten Mal auf das Servlet zugreift. Egal wie viele Clients auf das Servlet zugreifen, init() wird nie wiederholt ausgeführt.
Die standardmäßige init()-Methode erfüllt normalerweise die Anforderungen, kann aber auch mit einer benutzerdefinierten init()-Methode überschrieben werden, typischerweise zur Verwaltung serverseitiger Ressourcen. Beispielsweise könnten Sie ein benutzerdefiniertes init() schreiben, um ein GIF-Bild nur einmal zu laden und so die Leistung eines Servlets zu verbessern, das ein GIF-Bild zurückgibt und mehrere Client-Anfragen enthält. Ein weiteres Beispiel ist die Initialisierung einer Datenbankverbindung. Die Standardmethode init() legt die Initialisierungsparameter des Servlets fest und verwendet seine ServletConfig-Objektparameter, um die Konfiguration zu starten. Daher sollten alle Servlets, die die Methode init() überschreiben, super.init() aufrufen, um sicherzustellen, dass diese Aufgaben weiterhin ausgeführt werden. Bevor Sie die Methode service() aufrufen, sollten Sie sicherstellen, dass die Methode init() abgeschlossen wurde.

(2) service()-Methode
 Die service()-Methode ist der Kern von Servlet. Immer wenn ein Client ein HttpServlet-Objekt anfordert, wird die service()-Methode des Objekts aufgerufen und ein „request“-Objekt (ServletRequest) und ein „response“-Objekt (ServletResponse) als Parameter an diese Methode übergeben. Die service()-Methode existiert bereits in HttpServlet. Die Standarddienstfunktion besteht darin, die Do-Funktion aufzurufen, die der Methode der HTTP-Anforderung entspricht. Wenn die HTTP-Anforderungsmethode beispielsweise GET ist, wird standardmäßig doGet() aufgerufen. Servlets sollten die Do-Funktionalität für vom Servlet unterstützte HTTP-Methoden überschreiben. Da die Methode HttpServlet.service() prüft, ob die Anforderungsmethode den entsprechenden Handler aufruft, besteht keine Notwendigkeit, die Methode service() zu überschreiben. Überschreiben Sie einfach die entsprechende do-Methode und schon sind Sie fertig.
Wenn ein Client eine HTTP-POST-Anfrage über ein HTML-Formular stellt, wird die Methode doPost() aufgerufen. Mit der POST-Anfrage verknüpfte Parameter werden vom Browser als separate HTTP-Anfrage an den Server gesendet. Wenn Sie serverseitige Daten ändern müssen, sollten Sie die Methode doPost() verwenden.
Wenn ein Client eine HTTP-GET-Anfrage über ein HTML-Formular stellt oder direkt eine URL anfordert, wird die doGet()-Methode aufgerufen. Parameter im Zusammenhang mit der GET-Anfrage werden am Ende der URL hinzugefügt und mit dieser Anfrage gesendet. Die Methode doGet() sollte verwendet werden, wenn die serverseitigen Daten nicht geändert werden.
Die Antwort des Servlets kann von den folgenden Typen sein:
Ein Ausgabestream, den der Browser entsprechend seinem Inhaltstyp (z. B. Text/HTML) interpretiert.
Eine HTTP-Fehlerantwort, Weiterleitung zu einer anderen URL, einem anderen Servlet oder einer anderen JSP.

(3) destroy() 方法
  destroy() 方法仅执行一次,即在服务器停止且卸装Servlet 时执行该方法。典型的,将 Servlet 作为服务器进程的一部分来关闭。缺省的 destroy() 方法通常是符合要求的,但也可以覆盖它,典型的是管理服务器端资源。例如,如果 Servlet 在运行时会累计统计数据,则可以编写一个 destroy() 方法,该方法用于在未装入 Servlet 时将统计数字保存在文件中。另一个示例是关闭数据库连接。
当服务器卸装 Servlet 时,将在所有 service() 方法调用完成后,或在指定的时间间隔过后调用 destroy() 方法。一个Servlet 在运行service() 方法时可能会产生其它的线程,因此请确认在调用 destroy() 方法时,这些线程已终止或完成。

(4) GetServletConfig()方法
  GetServletConfig()方法返回一个 ServletConfig 对象,该对象用来返回初始化参数和  ServletContext。ServletContext 接口提供有关servlet 的环境信息。

(5) GetServletInfo()方法
  GetServletInfo()方法是一个可选的方法,它提供有关servlet 的信息,如作者、版本、版权。
  当服务器调用sevlet 的Service()、doGet()和doPost()这三个方法时,均需要 “请求”和“响应”对象作为参数。“请求”对象提供有关请求的信息,而“响应”对象提供了一个将响应信息返回给浏览器的一个通信途径。javax.servlet 软件包中的相关类为ServletResponse和ServletRequest,而javax.servlet.http 软件包中的相关类为HttpServletRequest 和 HttpServletResponse。Servlet 通过这些对象与服务器通信并最终与客户机通信。Servlet 能通过调用“请求”对象的方法获知客户机环境,服务器环境的信息和所有由客户机提供的信息。Servlet 可以调用“响应”对象的方法发送响应,该响应是准备发回客户机的。 

例子:
创建一个servlet


/** 
 * 
 */ 
package com.ee.servlet; 
 
import java.io.IOException; 
 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
 
/** 
 * @author Administrator 
 * 
 */ 
public class LogServlet extends HttpServlet { 
 
 /** 
  * 
  */ 
 private static final long serialVersionUID = 1L; 
 
 @Override 
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
   throws ServletException, IOException { 
  doPost(req, resp); 
 } 
  
 @Override 
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
   throws ServletException, IOException { 
  System.err.println("...doPost(req, resp)..."); 
 } 
}

在web.xml中的配置:


<servlet> 
 <servlet-name>LogServlet</servlet-name> 
 <servlet-class>com.ee.servlet.LogServlet</servlet-class> 
</servlet> 
 
<servlet-mapping> 
 <servlet-name>LogServlet</servlet-name> 
 <url-pattern>/*</url-pattern><!-- 看到此没有,这个拦截所有路径 --> 
</servlet-mapping>

它的拦截规则:

当一个请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url,比如我访问的是http://localhost/test/aaa.html,我的应用上下文是test,容器会将http://localhost/test去掉,剩下的/aaa.html部分拿来做servlet的映射匹配。这个映射匹配过程是有顺序的,而且当有一个servlet匹配成功以后,就不会去理会剩下的servlet了(filter不同,后文会提到)。其匹配规则和顺序如下:
1.精确路径匹配。例子:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先 进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,也不会去理会其他的servlet了。
2.最长路径匹配。例子:servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。
3.扩展匹配,如果url最后一段包含扩展,容器将会根据扩展选择合适的servlet。例子:servletA的url-pattern:*.action
4.如果前面三条规则都没有找到一个servlet,容器会根据url选择对应的请求资源。如果应用定义了一个default servlet,则容器会将请求丢给default servlet 

3、Listener功能

它是基于观察者模式设计的,Listener 的设计对开发 Servlet 应用程序提供了一种快捷的手段,能够方便的从另一个纵向维度控制程序和数据。目前 Servlet 中提供了 5 种两类事件的观察者接口,它们分别是:4 个 EventListeners 类型的,ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener 和 2 个 LifecycleListeners 类型的,ServletContextListener、HttpSessionListener。如下图所示: 

Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,这样就可以给在线人数加1。常用的监听接口有以下几个:

ServletContextAttributeListener监听对ServletContext属性的操作,比如增加、删除、修改属性。
ServletContextListener监听ServletContext。当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法;当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。
HttpSessionListener监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。
HttpSessionAttributeListener监听HttpSession中的属性的操作。当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。

下面我们开发一个具体的例子,这个监听器能够统计在线的人数。在ServletContext初始化和销毁时,在服务器控制台打印对应的信息。当ServletContext里的属性增加、改变、删除时,在服务器控制台打印对应的信息。
要获得以上的功能,监听器必须实现以下3个接口:

HttpSessionListener
ServletContextListener
ServletContextAttributeListener 

例子:


/** 
 * 
 */ 
package com.ee.listener; 
 
import javax.servlet.ServletContextAttributeEvent; 
import javax.servlet.ServletContextAttributeListener; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import javax.servlet.http.HttpSessionEvent; 
import javax.servlet.http.HttpSessionListener; 
 
/** 
 * @author Administrator 
 * 
 */ 
public class OnlineUserListener implements HttpSessionListener, 
  ServletContextListener, ServletContextAttributeListener { 
 private long onlineUserCount = 0; 
 
 public long getOnlineUserCount() { 
  return onlineUserCount; 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextAttributeListener#attributeAdded(javax.servlet.ServletContextAttributeEvent) 
  */ 
 @Override 
 public void attributeAdded(ServletContextAttributeEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextAttributeListener#attributeRemoved(javax.servlet.ServletContextAttributeEvent) 
  */ 
 @Override 
 public void attributeRemoved(ServletContextAttributeEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextAttributeListener#attributeReplaced(javax.servlet.ServletContextAttributeEvent) 
  */ 
 @Override 
 public void attributeReplaced(ServletContextAttributeEvent attributeEvent) { 
  System.err.println("...attributeReplaced..."); 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) 
  */ 
 @Override 
 public void contextDestroyed(ServletContextEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) 
  */ 
 @Override 
 public void contextInitialized(ServletContextEvent arg0) { 
 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent) 
  */ 
 @Override 
 public void sessionCreated(HttpSessionEvent httpSessionEvent) { 
  onlineUserCount ++; 
  toUpdateCount(httpSessionEvent); 
 } 
 
 /* (non-Javadoc) 
  * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent) 
  */ 
 @Override 
 public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { 
  onlineUserCount --; 
  toUpdateCount(httpSessionEvent); 
 } 
 
 private void toUpdateCount(HttpSessionEvent httpSessionEvent){ 
  httpSessionEvent.getSession().setAttribute("onlineUserCount", onlineUserCount); 
 } 
}

 Web.xml


<listener> 
 <listener-class>com.ee.listener.OnlineUserListener</listener-class> 
</listener>

 JSP页面:


<%@ page language="java" contentType="text/html; charset=UTF-8" 
 pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>主页</title> 
</head> 
<body> 
 <h4>你好!</h4> 
 在线人数:<h1><%=request.getSession().getAttribute("onlineUserCount") %></h1> 
</body> 
</html>

Das obige ist der detaillierte Inhalt vonEine detaillierte Einführung in Filter, Servlet und Listener in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn