Ich frage mich, ob es Filter
in Spring Boot Anmerkungen für eine Klasse (für Webanwendungen) gibt. Vielleicht @Filter
?
Ich möchte meinem Projekt einen benutzerdefinierten Filter hinzufügen.
Das erwähnte Spring Boot-Referenzhandbuch erwähnt
FilterRegistrationBean
, aber ich bin nicht sicher, wie ich es verwenden soll.
java
configuration
spring-boot
servlet-filters
janetsmith
quelle
quelle
Antworten:
Wenn Sie einen Filter eines Drittanbieters einrichten möchten, können Sie diesen verwenden
FilterRegistrationBean
. Zum Beispiel das Äquivalent von web.xmlDies sind die beiden Beans in Ihrer
@Configuration
DateiDas obige wurde mit Spring-Boot 1.2.3 getestet
quelle
someFilter()
direkt aufrufen .Hier ist ein Beispiel für eine Methode zum Einfügen eines benutzerdefinierten Filters in eine Spring Boot MVC-Anwendung. Stellen Sie sicher, dass Sie das Paket in einen Komponentenscan aufnehmen:
quelle
MetricsFilter
, aber diese Bean wird von der gleichnamigen Spring-Aktuator-Bean überschattet.Es gibt keine spezielle Anmerkung zur Bezeichnung eines Servlet-Filters. Sie deklarieren einfach einen
@Bean
TypFilter
(oderFilterRegistrationBean
). Ein Beispiel (Hinzufügen eines benutzerdefinierten Headers zu allen Antworten) befindet sich in der EndpointWebMvcAutoConfiguration von Boot .Wenn Sie nur a deklarieren
Filter
, wird es auf alle Anforderungen angewendet. Wenn Sie auch ein hinzufügenFilterRegistrationBean
, können Sie zusätzlich einzelne Servlets und URL-Muster angeben, die angewendet werden sollen.Hinweis:
Ab Spring Boot 1.4
FilterRegistrationBean
ist nicht veraltet und einfach Pakete vonorg.springframework.boot.context.embedded.FilterRegistrationBean
nach verschobenorg.springframework.boot.web.servlet.FilterRegistrationBean
quelle
Filter
auf Ihrem Klassenpfad haben. Normalerweise würde ich nur das verwendenspring-boot-starter-web
, um alle relevanten Abhängigkeiten einzuziehen (z . B. hier ).Es gibt drei Möglichkeiten, Ihren Filter hinzuzufügen:
@Component
@Bean
mitFilter
Typ im Frühjahr@Configuration
@Bean
mitFilterRegistrationBean
Typ im Frühjahr@Configuration
Entweder Nr. 1 oder Nr. 2 reicht aus, wenn Sie möchten, dass Ihr Filter auf alle Anforderungen ohne Anpassung angewendet wird. Andernfalls verwenden Sie Nr. 3. Sie müssen keinen Komponentenscan angeben, damit # 1 funktioniert, solange Sie Ihre Filterklasse im selben oder Unterpaket Ihrer
SpringApplication
Klasse platzieren. Für # 3 ist die Verwendung zusammen mit # 2 nur erforderlich, wenn Spring Ihre Filterklasse verwalten soll, z. B. automatisch verdrahtete Abhängigkeiten. Es funktioniert gut für mich, meinen Filter neu zu erstellen, für den keine automatische Verdrahtung / Injektion erforderlich ist.Obwohl das Kombinieren von # 2 und # 3 gut funktioniert, war ich überrascht, dass nicht zwei Filter zweimal angewendet werden. Ich vermute, dass Spring die beiden Bohnen als eine kombiniert, wenn es dieselbe Methode aufruft, um beide zu erstellen. Wenn Sie # 3 alleine mit authowiring verwenden möchten, können Sie dies tun
AutowireCapableBeanFactory
. Das Folgende ist ein Beispiel:quelle
Filter
während der VerwendungFilterRegistrationBean
UPDATE: 2017-12-16:
In Spring Boot 1.5.8.RELEASE gibt es zwei einfache Möglichkeiten, dies zu tun. XML ist nicht erforderlich.
Erster Weg: Wenn Sie kein räumliches URL-Muster haben, können Sie @Component wie folgt verwenden: (Vollständiger Code und Details finden Sie hier https://www.surasint.com/spring-boot-filter/ )
Zweiter Weg: Wenn Sie URL-Muster verwenden möchten, können Sie @WebFilter folgendermaßen verwenden: (Vollständiger Code und Details finden Sie hier https://www.surasint.com/spring-boot-filter-urlpattern/ )
Sie müssen Ihrer @ SpringBootApplication-Klasse jedoch auch die Annotation @ServletComponentScan hinzufügen:
Beachten Sie, dass @Component die Annotation von Spring ist, @WebFilter jedoch nicht. @WebFilter ist eine Servlet 3-Annotation.
In beiden Fällen benötigen Sie lediglich die grundlegende Spring Boot-Abhängigkeit in pom.xml (kein expliziter eingebetteter Tomcat-Jaspis erforderlich).
WARNUNG: Der erste Weg, wenn der Controller in Spring Boot zu einer JSP-Datei zurückkehrt, besteht die Anforderung den Filter zweimal.
Während die Anforderung auf die zweite Weise den Filter nur einmal durchläuft.
Ich bevorzuge den zweiten Weg, da er dem Standardverhalten in der Servlet-Spezifikation ähnlicher ist ( https://docs.oracle.com/cd/E19879-01/819-3669/6n5sg7b0b/index.html ).
Weitere Testprotokolle finden Sie hier https://www.surasint.com/spring-boot-webfilter-instead-of-component/
quelle
Filter
Schnittstelle beim Start des applicationContext mehrmals aufgerufen wurde. Gibt es eine Möglichkeit, es nur einmal auszuführen?Hier ist ein Beispiel für meine benutzerdefinierte Filterklasse:
Und ich habe es der Spring-Boot-Konfiguration hinzugefügt, indem ich es wie folgt zur Konfigurationsklasse hinzugefügt habe:
quelle
Aus Spring Docs,
Eingebettete Servlet-Container - Fügen Sie einer Anwendung ein Servlet, einen Filter oder einen Listener hinzu
Z.B:
Fügen Sie diese
@Bean
Konfiguration Ihrer@Configuration
Klasse hinzu, und der Filter wird beim Start registriert.Sie können Servlets, Filter und Listener auch mithilfe des Klassenpfad-Scannens hinzufügen.
quelle
Wenn Sie Spring Boot + Spring Security verwenden, können Sie dies in der Sicherheitskonfiguration tun.
Im folgenden Beispiel füge ich vor dem BenutzernamenPasswordAuthenticationFilter einen benutzerdefinierten Filter hinzu (siehe alle Standardfilter von Spring Security und deren Reihenfolge ).
Und die Filterklasse
quelle
Mit der Annotation @WebFilter können Sie wie folgt vorgehen:
quelle
Wir haben ungefähr vier verschiedene Möglichkeiten, einen Filter mit Spring zu registrieren .
Erstens können wir eine Spring Bean erstellen, die Filter implementiert oder HttpFilter erweitert :
Zweitens können wir eine Spring Bean erstellen, die GenericFilterBean erweitert :
Alternativ können wir die FilterRegistrationBean- Klasse verwenden:
Und schließlich können wir die Verwendung @WebFilter Annotation mit @ServletComponentScan :
quelle
Es ist eher ein Rat als eine Antwort, aber wenn Sie eine Spring MVC in Ihrer Webanwendung verwenden, ist es eine gute Idee, Spring HandlerInterceptor anstelle von Filter zu verwenden
Es kann den gleichen Job ausführen, aber auch - Kann mit ModelAndView arbeiten - Seine Methoden können vor und nach der Anforderungsverarbeitung oder nach Abschluss der Anforderung aufgerufen werden.
- Es kann leicht getestet werden
1 Implementieren Sie die HandlerInterceptor-Schnittstelle und fügen Sie Ihrer Klasse eine @ Component-Annotation hinzu
2 Konfigurieren Sie Ihren Interceptor
quelle
Dieser Filter hilft Ihnen auch dabei, den Cross-Origin-Zugriff zuzulassen
quelle
Sie können @WebFilter javax.servlet.annotation.WebFilter für eine Klasse verwenden, die javax.servlet.Filter implementiert
Verwenden Sie dann @ServletComponentScan, um sich zu registrieren
quelle
Ich habe hier viele Antworten gesehen, aber keine ausprobiert. Ich habe gerade den Filter wie im folgenden Code erstellt.
Und ließ die verbleibende Spring Boot-Anwendung so wie sie war.
quelle
Sie benötigen zwei wichtige Dinge: -
@ServletComponentScan
Zu Ihrer Hauptklasse hinzufügen - Sie können ein Paket mit dem Namen filter hinzufügen, in dem Sie eineFilter
Klasse erstellen , die Folgendes enthält:quelle
Sie können einen Filter auch mithilfe von @WebFilter erstellen und Filter implementieren.
quelle
Filter, wie der Name schon sagt, werden verwendet, um entweder die Anforderung an eine Ressource oder die Antwort einer Ressource oder beides zu filtern. Spring Boot bietet nur wenige Optionen zum Registrieren benutzerdefinierter Filter in der Spring Boot-Anwendung. Schauen wir uns die verschiedenen Optionen an.
1. Definieren Sie den Spring Boot Filter und die Aufrufreihenfolge
Implementieren Sie die Filterschnittstelle, um einen neuen Filter in Spring Boot zu erstellen.
Schauen wir uns kurz einige wichtige Punkte im obigen Code an
Um Filter in der richtigen Reihenfolge auszulösen, mussten wir die Annotation @Order verwenden .
Im obigen Code wird CustomFirstFilter vor dem CustomSecondFilter ausgeführt.
2. URL-Muster
Wenn die konventionelle Zuordnung nicht flexibel genug ist, können wir FilterRegistrationBean für die vollständige Steuerung der Anwendung verwenden. Verwenden Sie hier keine @ Component- Annotation für die Filterklasse, sondern registrieren Sie den Filter mit einer FilterRegistrationBean .
Registrieren Sie den benutzerdefinierten Filter mit FilterRegistrationBean .
quelle
Sie müssen Filter implementieren und mit @WebFilter (urlPatterns = "/ *") kommentiert werden.
Und in der Anwendungs- oder Konfigurationsklasse müssen Sie @ServletComponentScan hinzufügen. Dadurch wird Ihr Filter registriert.
quelle
@WebFilter
ist erst seit Servlet 3.0. Daher funktioniert es möglicherweise nicht richtig für 2.5Schritt 1: Erstellen Sie eine Filterkomponente, indem Sie die Filterschnittstelle implementieren.
Schritt 2: Setzen Sie diesen Filter mit FilterRegistrationBean auf die Uri-Muster.
Sie können diesen Link für die vollständige Anwendung verweisen .
quelle
@ServletComponentScan
Fügen Sie zunächst Ihrer SpringBootApplication-Klasse hinzu.Zweitens erstellen Sie eine Filterdatei, die Filter oder die Filterklasse eines Drittanbieters erweitert, und fügen Sie
@WebFilter
diese Datei wie folgt hinzu:quelle
Ich habe eine Antwort von @Vasily Komarov gesehen. Ähnlicher Ansatz, jedoch Verwendung der abstrakten HandlerInterceptorAdapter- Klasse anstelle von HandlerInterceptor .
Hier ist ein Beispiel...
quelle
Wie Sie alle wissen, ist Spring Boot eine wunderbare Möglichkeit, eine WebApp oder StandaloneApp mit minimaler Konfiguration und eigenwilligem Setup zu entwickeln.
Auf diese Weise habe ich eine Webfilterentwicklung in Spring Boot-Anwendung erreicht
Spring Boot-Version: 2.0.4.RELEASE
Java-Version: 8.0
Servlet-Spezifikation: Servlet 3.0 (obligatorisch und wichtig)
Ich habe meinen Webfilter wie folgt deklariert und dabei die Servlet-Spezifikationen 3.0 eingehalten
Dies ist die programmatische Methode zum Definieren eines Filters als Ersatz für web.xml-basierte Definitionen.
Die Annotation "@Webfilter" wird vom Container während der Bereitstellung verarbeitet. Die Filterklasse, in der sie gefunden wird, wird gemäß der Konfiguration erstellt und auf die URL-Muster javax.servlet.Servlets und javax.servlet.DispatcherTypes angewendet.
Um die Spring Boot-Anwendung als "traditionelles WAR" bereitzustellen, sollte die Anwendungsklasse SpringBootServletInitializer erweitern.
HINWEIS :: SpringBootServletInitializer ist eine "programmatische Implementierung" von web.xml unter Bezugnahme auf Servlet 3.0+ -Spezifikationen, für die eine Implementierung von WebApplicationInitializer erforderlich ist.
Daher benötigt SpringBootApplication nicht "web.xml", da die Anwendungsklasse (nach Erweiterung von SpringBootServletInitializer) nach
- @WebFilter,
- @WebListener und
- @WebServlet sucht.
Diese Annotation ermöglicht das Scannen von Basispaketen für die mit @WebFilter, @WebListener und @WebServlet annotierten Webkomponenten.
Aufgrund der Tatsache, dass eingebettete Container die Annotationen @WebServlet, @WebFilter und @WebListener nicht unterstützen, hat Spring Boot, das sich stark auf eingebettete Container stützt, diese neue Annotation @ServletComponentScan eingeführt, um einige abhängige Jars zu unterstützen, die diese 3 Annotationen verwenden.
Das Scannen wird nur durchgeführt, wenn ein eingebetteter Servlet-Container verwendet wird.
Hier: Ich habe eine benutzerdefinierte Klasse definiert: "ServletInitializer", die die Klasse: SpringBootServletInitializer erweitert.
Wie bereits erläutert, ist SpringBootServletInitializer für das Scannen von Anmerkungen verantwortlich: -
- @WebFilter,
- @WebListener und
- @WebServlet.
Und daher sollte die Spring Boot-Anwendungsklasse
quelle
Filter werden hauptsächlich in Logger-Dateien verwendet. Sie variieren je nach dem Logger, den Sie im Projekt Lemme EXPLAIN für log4j2 verwenden:
Filter werden verwendet, um die Daten einzuschränken, und ich habe den Schwellenwertfilter weiter verwendet, um die Datenebenen im Fluss einzuschränken. Ich habe die Ebenen erwähnt, die dort eingeschränkt werden können. Weitere Informationen finden Sie in der Levelreihenfolge von log4j2 - Log4J Levels: ALL> TRACE> DEBUG> INFO> WARN> ERROR> FATAL> OFF
quelle
FilterRegistrationBean
Wie in der Frage erwähntjavax.servlet.Filter
, spricht diese Antwort fürorg.apache.logging.log4j.core.Filter