codestory

Die Anleitung zu Java Servlet Filter

  1. Die Vorstellung
  2. Tại sao cần Server-Filter?
  3. Was kann Servlet-Filter tun?
  4. Erstellen Sie Projekt, um mit Servlet-Filter zu beginnen
  5. Konfigurieren zum Ausführen
  6. Das erste Servlet-Filter Beispiel
  7. Das Arbeitsmodell vom Filter
  8. Das Initalisierungsparameter vom Servlet-Filter
  9. Servlet-Filter url-pattern
  10. Servlet-Filter benutzt Annotation
  11. Die Einstellung zur Verbindung JDBC im Filter
  12. Die Anleitung zur Programmierung von JSP

1. Die Vorstellung

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

2. Tại sao cần Server-Filter?

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:
  1. Der Benutzer schickt eine Anforderung für das Sehen seiner privaten Information.
  2. Die Anforderung wird zum Server geschickt.
  3. Sie geht durch Filter des Aufschreiben der log Information .
  4. 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

3. Was kann Servlet-Filter tun?

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

4. Erstellen Sie Projekt, um mit Servlet-Filter zu beginnen

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>

5. Konfigurieren zum Ausführen

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

6. Das erste Servlet-Filter Beispiel

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);

7. Das Arbeitsmodell vom Filter

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

8. Das Initalisierungsparameter vom Servlet-Filter

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>

9. Servlet-Filter url-pattern

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
/status/abc/*
http://example.com/contextPath/status/abc/mnp
/status/abc/*
http://example.com/contextPath/status/abc/mnp?date=today
/status/abc/*
http://example.com/contextPath/test/abc/mnp
*.map
http://example.com/contextPath/status/abc.map
*.map
http://example.com/contextPath/status.map?date=today
*.map
http://example.com/contextPath/status/abc.MAP

10. Servlet-Filter benutzt Annotation

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.
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);

11. Die Einstellung zur Verbindung JDBC im Filter

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();

12. Die Anleitung zur Programmierung von JSP

Zum nächsten können Sie JSP studieren