Inhaltsverzeichnis
- Die Vorstellung
- Why need Server-Filter?
- Was kann Servlet-Filter tun?
- Create Project to start with Servlet-Filter
- Configuring the runtime environment
- The first Servlet-Filter example
- Das Arbeitsmodell vom Filter
- Das Initalisierungsparameter vom Servlet-Filter
- Servlet-Filter url-pattern
- Servlet-Filter benutzt Annotation
- Die Einstellung zur Verbindung JDBC im Filter
- Die Anleitung zur Programmierung von JSP
Die Anleitung zu Java Servlet Filter
View more Tutorials:
- Die Vorstellung
- Why need Server-Filter?
- Was kann Servlet-Filter tun?
- Create Project to start with Servlet-Filter
- Configuring the runtime environment
- The first Servlet-Filter example
- Das Arbeitsmodell vom Filter
- Das Initalisierungsparameter vom Servlet-Filter
- Servlet-Filter url-pattern
- Servlet-Filter benutzt Annotation
- Die Einstellung zur Verbindung JDBC im Filter
- Die Anleitung zur Programmierung von JSP

Das Dokument wird auf die Basic von ... geschrieben:
-
Eclipse 4.6 NEON
-
Tomcat 8.x
Sie sollen die Kenntnisse von Servlet haben vor dem Lesen des Dokument über Servlet-Filter,. Wenn Sie die Anfänger sind, können Sie Java Servlet bei ... lernen
Die Situation 1:
Wenn der Benutzer eine Website erfordert, wird eine Anforderung zum Server geschickt. Und sie muss durch einen Filter vor dem Eingang zur geforderten Seite gehen. Wie das folgende Beispiel

Die Situation 2
Allerdings gibt es einige Situation, in der die Anforderungen des Benutzer durch alle Etage des Filter nicht gehen

Die Situation 3:
Falls der Benutzer eine Anforderung nach einer Seite (page1),Die Anforderung wird durch Filter durchgehen, Und bei einem Filter wird die Anforderung nach einer anderen Seite (page2) umgeleitet
DIe Situation zum Beispiel:
- Der Benutzer schickt eine Anforderung für das Sehen seiner privaten Information.
- Die Anforderung wird zum Server geschickt.
- Sie geht durch Filter des Aufschreiben der log Information .
- Er geht durch Filter der Prüfung des Log-in. Wenn der Filter prüft und fand der Benutzer nicht anmeldet, leitet er die Anforderung des Benutzer nach der Login Seite

Manchmal denken Sie daran, Filter ist nur für die Umleitung der Anforderung vom Benutzer zur anderen Seite oder für die Verhinderung des Zugang einer Seite wenn der Benutzer keinen Recht hat. Oder für die Aufschreiben der Log Information.
In dem Praxis kann Filter für die Kodierung (encoding) einer Webseite benutzt werden. Zum Beispiel von Kodierung UTF-8 für die Seite. Öffen und die Verbindung mit Database lösen und auf die Transaktion JDBC vorbereiten
Zuerst erstellen wir ein WebApp project um mit Servlet-Filter.zu arbeiten
- File/New/Other...

geben Sie ein
- Project Name: ServletFilterTutorial



Das Project wird erstellt:

Erstellen Sie eine File index.html:

index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Home Page</title> </head> <body> <h2>Servlet-Filter Tutorial</h2> </body> </html>
Drücken Sie die Rechtmaustaste ins Project und wählen Sie Properties:




Klicken Sie die Rechtmaustaste ins Project und wählen Sie :
- Run As/Run on Server




OK!, Alle ist bereit, um Servlet-Filter.zu studieren
Servlet Filter ist eine Class für die Implementierung der Interface javax.servlet.Filter. Class LogFilter unten schreibt die Zeit und den Pfad der Anforderung zu WebApp
LogFilter.java
package org.o7planning.tutorial.servletfilter; import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class LogFilter implements Filter { public LogFilter() { } @Override public void init(FilterConfig fConfig) throws ServletException { System.out.println("LogFilter init!"); } @Override public void destroy() { System.out.println("LogFilter destroy!"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String servletPath = req.getServletPath(); System.out.println("#INFO " + new Date() + " - ServletPath :" + servletPath // + ", URL =" + req.getRequestURL()); // Genehmigen, die Request weiter zu gehen. (durch den Filter). chain.doFilter(request, response); } }
Configure filter in web.xml:
Fügen Sie die Konfiguration in web.xml:
<!-- Declaring a filter named logFilter --> <filter> <filter-name>logFilter</filter-name> <filter-class>org.o7planning.tutorial.servletfilter.LogFilter</filter-class> </filter> <!-- Declare the path (of the page) will have the effect of logFilter /* for all paths --> <filter-mapping> <filter-name>logFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ServletFilterTutorial</display-name> <filter> <filter-name>logFilter</filter-name> <filter-class>org.o7planning.tutorial.servletfilter.LogFilter</filter-class> </filter> <filter-mapping> <filter-name>logFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
Starten Sie Ihre Applikation

Sie können die folgenden Pfad auf dem Browser laufen. Hier gibt es die Pfad zur die Quelle, die nicht im Ihren WebApp vorhanden sind. Aber es wird von LogFilter beeinflusst

Die Log Information wird auf die Bildschirm Console aufgeschrieben

Die folgende Code ermöglicht die Anforderung bei dem Überholen der Filter um die Zielseite zu erreichen
// Genehmigen, die Request weiter vorwärts zu gehen. // Sie kann zum nächsten Filter oder dem Ziel gehen chain.doFilter(request, response);
Wenn der Benutzer eine Anforderung schickt, kann das Ziel (target) eine Resource oder einen Servlet sein. Die Anforderung soll durch die Filter Etage gehen und in das Ziel erreichen. Die Filter und das Ziel werden miteinander wie das folgende Beispiel verkettet

Benutzen Sie chain.doFilter(request,response) um die Anforderung zum nächsten Kettenglied zu bewegen. Wenn chain.doFilter(request, response) im Filter nicht aufgeruft wird, kann die Anforderung der Benutzer ins Ziel nicht erreichen. Es wird bei diesem Filter gehaltet
Wie Servlet können Sie die Parameter für Filter bauen. Das folgende Beispiel: Ein Filter hat ein Aufgabe vom Aufschreiben der Log in einer File. Sie können in web.xml den Name von File konfigurieren um zu schreiben
Log2Filter.java
package org.o7planning.tutorial.servletfilter; 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; public class Log2Filter implements Filter { private String logFile; public Log2Filter() { } @Override public void init(FilterConfig fConfig) throws ServletException { this.logFile = fConfig.getInitParameter("logFile"); System.out.println("Log File " + logFile); } @Override public void destroy() { System.out.println("Log2Filter destroy!"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (this.logFile != null) { // Die Log Information in die File aufschreiben. this.logToFile(this.logFile); } // Die Request weiter gehen. (durch den Filter). chain.doFilter(request, response); } private void logToFile(String fileName) { // Die Log in die File aufschreiben System.out.println("Write log to file " + fileName); } }
Fügen Sie die Konfiguration in web.xml:ein
<filter> <filter-name>log2Filter</filter-name> <filter-class>org.o7planning.tutorial.servletfilter.Log2Filter</filter-class> <init-param> <param-name>logFile</param-name> <param-value>AppLog.log</param-value> </init-param> </filter> <filter-mapping> <filter-name>log2Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ServletFilterTutorial</display-name> <filter> <filter-name>logFilter</filter-name> <filter-class>org.o7planning.tutorial.servletfilter.LogFilter</filter-class> </filter> <filter-mapping> <filter-name>logFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>log2Filter</filter-name> <filter-class>org.o7planning.tutorial.servletfilter.Log2Filter</filter-class> <init-param> <param-name>logFile</param-name> <param-value>AppLog.log</param-value> </init-param> </filter> <filter-mapping> <filter-name>log2Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
Es gibt 3 Modelle, damit Sie url-pattern für Filter konfigurieren:
URL Pattern | Example |
/* | http://example.com/contextPath |
http://example.com/contextPath/status/abc | |
/status/abc/* | http://example.com/contextPath/status/abc |
http://example.com/contextPath/status/abc/mnp | |
http://example.com/contextPath/status/abc/mnp?date=today | |
*.map | http://example.com/contextPath/status/abc.map |
http://example.com/contextPath/status.map?date=today | |
Die oben Beispiel über die Konfiguration der Filter im web.xml, Aber mit der WebApp ab Version 3 können Sie die Annotation benutzen um für Filter zu konfigurieren.
Das Beispiel bezeichnet, wenn der Benutzer eine Anforderung zum Ansehen einer Foto File (jpd, png oder gif) schickt, wird der Filter prüfen, ob diese Foto file existiert oder nicht. Wenn nicht, wird der Filter die Anforderung zur standardmäßigen File umgeleitet.
Das Beispiel bezeichnet, wenn der Benutzer eine Anforderung zum Ansehen einer Foto File (jpd, png oder gif) schickt, wird der Filter prüfen, ob diese Foto file existiert oder nicht. Wenn nicht, wird der Filter die Anforderung zur standardmäßigen File umgeleitet.
Zuerst kopieren Sie die 2 Foto File flower.png & image-not-found.png in dem Ordner images auf Ihre WebApp

ImageFilter.java
package org.o7planning.tutorial.servletfilter; import java.io.File; 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; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebFilter(urlPatterns = { "*.png", "*.jpg", "*.gif" }, initParams = { @WebInitParam(name = "notFoundImage", value = "/images/image-not-found.png") }) public class ImageFilter implements Filter { private String notFoundImage; public ImageFilter() { } @Override public void init(FilterConfig fConfig) throws ServletException { // ==> /images/image-not-found.png notFoundImage = fConfig.getInitParameter("notFoundImage"); } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; // ==> /images/path/my-image.png // ==> /path1/path2/image.pngs String servletPath = req.getServletPath(); // Der absolute Pfad des Hauptverzeichnis vom WebApp (WebContent). String realRootPath = request.getServletContext().getRealPath(""); // Der absolute Pfad zur Foto-File. String imageRealPath = realRootPath + servletPath; System.out.println("imageRealPath = " + imageRealPath); File file = new File(imageRealPath); // Prüfen, ob das Foto existiert oder nicht. if (file.exists()) { // Genehmigen, die Request weiter zu gehen (durch den Filter). // (um zur angeforderten Fotofile zu gehen). chain.doFilter(request, response); } else if (!servletPath.equals(this.notFoundImage)) { // Zur die Foto-File 'image not found' umleiten (redirect). HttpServletResponse resp = (HttpServletResponse) response; // ==> /ServletFilterTutorial + /images/image-not-found.png resp.sendRedirect(req.getContextPath() + this.notFoundImage); } } }
Starten Sie Ihre Applikation wieder und laufen Sie die folgenden URL

Im Fall vom Pfad der Anforderung nach der Foto File aber die File existiert nicht wird es zum standardmäßigen Foto umgeleitet.

Im oben Beispiel können Sie die Anforderung zum standardmäßigen Foto weiterleiten (forward) statt umleiten (redirect) wenn das angeforderte Foto existiert nicht
// Redirect: // ==> /ServletFilterTutorial + /images/image-not-found.png response.sendRedirect(request.getContextPath()+ this.notFoundImage); // Forward: request.getServletContext().getRequestDispatcher(this.notFoundImage).forward(request, response);
Sie können ein JDBC verbindendes Object Connection im Servlet erstellen um die Aufgabe mit Database durchzuführen. Aber Sie können ein JDBC verbindendes Object Connection im Filter und es hat die Auswirkung mit vieler Servlet. Und Sie können die Connection während der Reise der Anforderung. Sie können das folgende Beispiel um mehr zu verstehen:

ConnectionUtils ist eine Class, die das Objekt Connection verbindend mit der Database erstellt. Im Dokument stelle ich nicht vor, wie Sie das Object Connection erstellen können
Sie können die Unterlagen über JDBC lesen bei ...
ConnectionUtils.java
package org.o7planning.tutorial.servletfilter.conn; import java.sql.Connection; public class ConnectionUtils { public static Connection getConnection() { // Eine Verbindung (connection) zur Database erstellen Connection conn = null; // ..... return conn; } public static void closeQuietly(Connection conn) { try { conn.close(); } catch (Exception e) { } } public static void rollbackQuietly(Connection conn) { try { conn.rollback(); } catch (Exception e) { } } }
MyUtils.java
package org.o7planning.tutorial.servletfilter.conn; import java.sql.Connection; import javax.servlet.ServletRequest; public class MyUtils { public static final String ATT_NAME = "MY_CONNECTION_ATTRIBUTE"; // Das Objekt Connection in einer Attribute von der Request // Die Information zur Archivierung existiert in der Zeitraum von Request zum // wenn die Daten nach den Benutzersbrowser zurückgegeben werden public static void storeConnection(ServletRequest request, Connection conn) { request.setAttribute(ATT_NAME, conn); } // Das Objekt Connection, das in einer Attribute der Request archiviert wird, entnehmen public static Connection getStoredConnection(ServletRequest request) { Connection conn = (Connection) request.getAttribute(ATT_NAME); return conn; } }
Ich melde url-pattern für den JDBCFilter als /* an. Der Filter ist effektiv für die alle Anforderungen des Benutzer
JDBCFilter.java
package org.o7planning.tutorial.servletfilter.conn; import java.io.IOException; import java.sql.Connection; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; @WebFilter(urlPatterns = { "/*" }) public class JDBCFilter implements Filter { public JDBCFilter() { } @Override public void init(FilterConfig fConfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; // String servletPath = req.getServletPath(); // Die Verbindung (connection) für die Request mit den besonderen Pfad nur öffnen // ( Z.B den Pfad zum servlet, jsp ...) // vermeinden, die Connection für die normalen Anforderungen zu öffnen // (Z. B image, css, javascript,... ) if (servletPath.contains("/specialPath1") || servletPath.contains("/specialPath2")) { Connection conn = null; try { // Ein Objekt Connection mit Database erstellen. conn = ConnectionUtils.getConnection(); // Automatisch commit = false einstellen um aktiv zu kontrollieren. conn.setAutoCommit(false); // Die Attribute von Request archivieren. MyUtils.storeConnection(request, conn); // Genehmigen, die Request weiter zu gehen (durch den Filter). chain.doFilter(request, response); // Die Aufruf auf commit() um die Transaction mit DB zu erledigen. conn.commit(); } catch (Exception e) { ConnectionUtils.rollbackQuietly(conn); throw new ServletException(); } finally { ConnectionUtils.closeQuietly(conn); } } // Für die normalen Anforderungen. else { // Genehmigen, die Request weiter zu gehen (durch den Filter). chain.doFilter(request, response); } } }
Beim nächsten Filter oder bei dem Servlet oder bei der Seite JSP (auf einer gleichen Anforderung) können Sie das Object Connection nehmen, das im Attribute der Anforderung gespeichert wird
Connection conn = (Connection) request.getAttribute(ATT_NAME); // Oder Connection conn = MyUtils.getStoredConnection();
Zum nächsten können Sie JSP studieren