Java Servlet Filter wird verwendet, um die Client-Anfrage abzufangen und eine Vorverarbeitung durchzuführen. Es kann auch die Antwort abfangen und eine Nachverarbeitung durchführen, bevor sie an den Client in einer Webanwendung gesendet wird. Dies ist der vierte Artikel in der Reihe Web Applications Tutorial, Sie können auch frühere Artikel überprüfen.
Servlet Filter
In diesem Artikel werden wir den Servlet Filter in Java kennenlernen. Wir werden uns verschiedene Verwendungen von Servlet Filter ansehen, wie man einen Filter erstellt und seine Verwendung anhand einer einfachen Webanwendung erlernen.
-
Warum haben wir Servlet-Filter?
In dem letzten Artikel haben wir gelernt, wie wir eine Sitzung in einer Webanwendung verwalten können und wenn wir sicherstellen möchten, dass eine Ressource nur zugänglich ist, wenn die Benutzersitzung gültig ist, können wir dies mit Hilfe von Servlet-Sitzungsattributen erreichen. Der Ansatz ist einfach, aber wenn wir viele Servlets und JSPs haben, wird es aufgrund von redundantem Code schwer zu pflegen sein. Wenn wir den Attributnamen in Zukunft ändern möchten, müssen wir alle Stellen ändern, an denen wir eine Sitzungsauthentifizierung haben. Deshalb haben wir einen Servlet-Filter. Servlet-Filter sind plugbare Java-Komponenten, die wir verwenden können, um Anfragen abzufangen und zu verarbeiten, bevor sie an Servlets gesendet werden, und Antworten, nachdem der Servlet-Code fertig ist und bevor der Container die Antwort an den Client zurücksendet. Einige gängige Aufgaben, die wir mit Servlet-Filtern erledigen können, sind:
- Protokollieren von Anfrageparametern in Protokolldateien.
- Authentifizierung und Autorisierung von Anfragen für Ressourcen.
- Formatierung des Anfragekörpers oder -headers, bevor er an das Servlet gesendet wird.
- Komprimieren der an den Client gesendeten Antwortdaten.
- Ändern der Antwort durch Hinzufügen von Cookies, Header-Informationen usw.
Wie ich bereits erwähnt habe, sind Servlet-Filter plugbar und werden in der Bereitstellungsbeschreibung (web.xml) konfiguriert. Servlets und Filter sind sich beide nicht bewusst und wir können einen Servlet-Filter einfach durch Bearbeiten von web.xml hinzufügen oder entfernen. Wir können mehrere Filter für eine einzelne Ressource haben und wir können eine Filterkette für eine einzelne Ressource in web.xml erstellen. Wir können einen Servlet-Filter erstellen, indem wir das
javax.servlet.Filter
-Interface implementieren. -
Servletrahmen Filter Schnittstelle
Die Servletrahmen Filter Schnittstelle ähnelt der Servletrahmen Schnittstelle und wir müssen sie implementieren, um unseren eigenen Servletrahmen Filter zu erstellen. Die Servletrahmen Filter Schnittstelle enthält Lebenszyklusmethoden eines Filters und wird vom Servletrahmencontainer verwaltet. Die Lebenszyklusmethoden der Servletrahmen Filter Schnittstelle sind:
- void init(FilterConfig paramFilterConfig) – Wenn der Container den Filter initialisiert, wird diese Methode aufgerufen. Diese Methode wird nur einmal im Lebenszyklus des Filters aufgerufen und wir sollten alle Ressourcen in dieser Methode initialisieren. FilterConfig wird vom Container verwendet, um Initialisierungsparameter und den Servletrahmenkontext an den Filter bereitzustellen. In dieser Methode können wir ServletException auslösen.
- doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – Diese Methode wird jedes Mal vom Container aufgerufen, wenn er einen Filter auf eine Ressource anwenden muss. Der Container stellt Referenzen auf die Anfrage- und Antwortobjekte als Argument an den Filter bereit. FilterChain wird verwendet, um den nächsten Filter in der Kette aufzurufen. Dies ist ein gutes Beispiel für das Ketten von Verantwortlichkeitsmuster.
- void destroy() – Wenn der Container die Filterinstanz entlädt, ruft er die destroy()-Methode auf. Dies ist die Methode, in der wir alle Ressourcen schließen können, die vom Filter geöffnet wurden. Diese Methode wird nur einmal im Lebenszyklus des Filters aufgerufen.
-
Servlet-Webfilterannotation
javax.servlet.annotation.WebFilter
wurde in Servlet 3.0 eingeführt und wir können diese Annotation verwenden, um einen Servlet-Filter zu deklarieren. Wir können diese Annotation verwenden, um Init-Parameter, Filternamen und -beschreibungen, Servlets, URL-Muster und Dispatchertypen zu definieren, um den Filter anzuwenden. Wenn Sie häufig Änderungen an den Filterkonfigurationen vornehmen, ist es besser, web.xml zu verwenden, da dies nicht erfordert, dass Sie die Filterklasse neu kompilieren müssen. Lesen: Java-Annotations-Tutorial -
Servlet-Filterkonfiguration in der web.xml
Wir können einen Servlet-Filter in der web.xml wie folgt deklarieren.
<filter> <filter-name>RequestLoggingFilter</filter-name> <!-- obligatorisch --> <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class> <!-- obligatorisch --> <init-param> <!-- optional --> <param-name>test</param-name> <param-value>testWert</param-value> </init-param> </filter>
Wir können einen Filter den Servlet-Klassen oder URL-Mustern wie folgt zuordnen.
<filter-mapping> <filter-name>RequestLoggingFilter</filter-name> <!-- obligatorisch --> <url-pattern>/*</url-pattern> <!-- entweder url-pattern oder servlet-name ist obligatorisch --> <servlet-name>LoginServlet</servlet-name> <dispatcher>REQUEST</dispatcher> </filter-mapping>
Hinweis: Bei der Erstellung der Filterkette für ein Servlet verarbeitet der Container zuerst die URL-Muster und dann die Servlet-Namen. Wenn Sie sicherstellen müssen, dass Filter in einer bestimmten Reihenfolge ausgeführt werden, achten Sie beim Definieren der Filterzuordnung besonders darauf. Servlet-Filter werden im Allgemeinen für Clientanfragen verwendet, aber manchmal möchten wir auch Filter mit RequestDispatcher anwenden. In diesem Fall können wir das Dispatcher-Element verwenden, die möglichen Werte sind REQUEST, FORWARD, INCLUDE, ERROR und ASYNC. Wenn kein Dispatcher definiert ist, wird der Filter nur auf Clientanfragen angewendet.
-
Servlet-Filter-Beispiel für Protokollierung und Sitzungsvalidierung
In our **servlet filter example**, we will create filters to log request cookies and parameters and validate session to all the resources except static HTMLs and LoginServlet because it will not have a session. We will create a dynamic web project **ServletFilterExample** whose project structure will look like the below image. [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Example-Project.png) login.html is the entry point of our application where the user will provide the login id and password for authentication. login.html code:
```
Login Page
```
LoginServlet is used to authenticate the request from the client for login.
```
package com.journaldev.servlet.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final String userID = "admin";
private final String password = "password";
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// Anforderungsparameter für BenutzerID und Passwort abrufen
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
if(userID.equals(user) && password.equals(pwd)){
HttpSession session = request.getSession();
session.setAttribute("user", "Pankaj");
// Sitzung auf Ablauf in 30 Minuten setzen
session.setMaxInactiveInterval(30*60);
Cookie userName = new Cookie("user", user);
userName.setMaxAge(30*60);
response.addCookie(userName);
response.sendRedirect("LoginSuccess.jsp");
}else{
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
PrintWriter out= response.getWriter();
out.println("Either user name or password is wrong.");
rd.include(request, response);
}
}
}
```
When the client is authenticated, it's forwarded to LoginSuccess.jsp LoginSuccess.jsp code:
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
Login Success Page
<%
// Zugriff nur zulassen, wenn Sitzung vorhanden ist
String user = (String) session.getAttribute("user");
String userName = null;
String sessionID = null;
Cookie[] cookies = request.getCookies();
if(cookies !=null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("user")) userName = cookie.getValue();
if(cookie.getName().equals("JSESSIONID")) sessionID = cookie.getValue();
}
}
%>
Hi <%=userName %>, Login successful. Your Session ID=<%=sessionID %>
User=<%=user %>
Checkout Page
```
Notice that there is no session validation logic in the above JSP. It contains a link to another JSP page, CheckoutPage.jsp. CheckoutPage.jsp code:
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
Login Success Page
<%
String userName = null;
String sessionID = null;
Cookie[] cookies = request.getCookies();
if(cookies !=null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("user")) userName = cookie.getValue();
}
}
%>
Hi <%=userName %>, do the checkout.
```
LogoutServlet is invoked when a client clicks on the Logout button in any of the JSP pages.
```
package com.journaldev.servlet.session;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class LogoutServlet
*/
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("JSESSIONID")){
System.out.println("JSESSIONID="+cookie.getValue());
break;
}
}
}
// Sitzung ungültig machen, wenn vorhanden
HttpSession session = request.getSession(false);
System.out.println("User="+session.getAttribute("user"));
if(session != null){
session.invalidate();
}
response.sendRedirect("login.html");
}
}
```
Now we will create logging and authentication servlet filter classes.
```
package com.journaldev.servlet.filters;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* Servlet Filter implementation class RequestLoggingFilter
*/
@WebFilter("/RequestLoggingFilter")
public class RequestLoggingFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
this.context.log("RequestLoggingFilter initialized");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
Enumeration params = req.getParameterNames();
while(params.hasMoreElements()){
String name = params.nextElement();
String value = request.getParameter(name);
this.context.log(req.getRemoteAddr() + "::Request Params::{"+name+"="+value+"}");
}
Cookie[] cookies = req.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
this.context.log(req.getRemoteAddr() + "::Cookie::{"+cookie.getName()+","+cookie.getValue()+"}");
}
}
// Anfrage durch Filterkette weiterleiten
chain.doFilter(request, response);
}
public void destroy() {
// Ressourcen hier schließen
}
}
```
```
package com.journaldev.servlet.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebFilter("/AuthenticationFilter")
public class AuthenticationFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
this.context.log("AuthenticationFilter initialized");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();
this.context.log("Requested Resource::"+uri);
HttpSession session = req.getSession(false);
if(session == null && !(uri.endsWith("html") || uri.endsWith("LoginServlet"))){
this.context.log("Unauthorized access request");
res.sendRedirect("login.html");
}else{
// Anfrage durch Filterkette weiterleiten
chain.doFilter(request, response);
}
}
public void destroy() {
// Hier alle Ressourcen schließen
}
}
```
Notice that we are not authenticating any HTML page or LoginServlet. Now we will configure these filters mapping in the web.xml file.
```
ServletFilterExample
login.html
RequestLoggingFilter
com.journaldev.servlet.filters.RequestLoggingFilter
AuthenticationFilter
com.journaldev.servlet.filters.AuthenticationFilter
RequestLoggingFilter
/*
REQUEST
AuthenticationFilter
/*
```
Now when we will run our application, we will get response pages like below images. [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login.png) [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login-Success.png) [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Checkout.png) If you are not logged in and try to access any JSP page, you will be forwarded to the login page. In the server log file, you can see the logs written by servlet filters as well as servlets.
```
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Unauthorized access request
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Request Params::{pwd=password}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Request Params::{user=admin}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginServlet
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/CheckoutPage.jsp
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LogoutServlet
JSESSIONID=8BDF777933194EDCAC1D8F1B73633C56
User=Pankaj
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
Aug 13, 2013 1:07:06 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Unauthorized access request
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
```
Das war alles für den Servlet-Filter in Java. Es ist eine der wichtigen Funktionen der Java-EE-Webanwendung und wir sollten sie für gängige Aufgaben verwenden, die von verschiedenen Servlets ausgeführt werden. In zukünftigen Beiträgen werden wir uns Servlet-Listener und Cookies ansehen. Update: Nach vielen Anfragen nach dem herunterladbaren Projekt habe ich es dem Beitrag angehängt, laden Sie es über den folgenden Link herunter.
Servlet-Filter-Beispielprojekt herunterladen
Schau dir den nächsten Artikel in der Serie über Servlet-Listener an. Aktualisierung Struts 2 verwendet Servlet-Filter, um die Client-Anfragen abzufangen und sie an geeignete Aktionsklassen weiterzuleiten. Diese werden als Struts 2 Interceptors bezeichnet. Schau dir das Struts 2 Anfänger-Tutorial an.
Source:
https://www.digitalocean.com/community/tutorials/java-servlet-filter-example-tutorial