Was ist ein Filter?
Ein Filter ist eine Funktion der J2EE-Standard-Spezifikation, die es ermöglicht, vor/nach der Weiterleitung einer Anfrage an das Dispatcher Servlet zusätzliche Aufgaben für alle Anfragen zu einem bestimmten URL-Muster zu verarbeiten. Das heißt, die Verwaltung erfolgt durch den Web-Container wie Tomcat und nicht durch den Spring-Container, sodass die Anfrage vor dem Erreichen des Dispatcher Servlets verarbeitet wird.
Filter-Implementierung
Um einen Filter hinzuzufügen, muss das Filter-Interface von javax.servlet implementiert werden. Dieses Interface verfügt über die folgenden drei Methoden.
- init-Methode
- Diese Methode dient zur Initialisierung des Filter-Objekts und zum Hinzufügen zum Service. Der Web-Container ruft die init-Methode einmal auf, um das Filter-Objekt zu initialisieren. Anschliessend werden nachfolgende Anfragen über die doFilter()-Methode verarbeitet.
- doFilter-Methode
- Diese Methode wird vom Web-Container ausgeführt, bevor alle HTTP-Anfragen, die mit dem URL-Muster übereinstimmen, an das Dispatcher Servlet weitergeleitet werden. Sie wird auch vom Web-Container ausgeführt, bevor das Dispatcher Servlet die HTTP-Antwort an den Client sendet.
Der Parameter der doFilter()-Methode ist FilterChain. Mit doFilter() von FilterChain wird die Anfrage an das nächste Ziel weitergeleitet. Durch Einfügen des gewünschten Verarbeitungsprozesses vor/nach chain.doFilter() kann die gewünschte Verarbeitung durchgeführt werden.
- Diese Methode wird vom Web-Container ausgeführt, bevor alle HTTP-Anfragen, die mit dem URL-Muster übereinstimmen, an das Dispatcher Servlet weitergeleitet werden. Sie wird auch vom Web-Container ausgeführt, bevor das Dispatcher Servlet die HTTP-Antwort an den Client sendet.
- destroy-Methode
- Diese Methode dient zum Entfernen des Filter-Objekts aus dem Service und zur Rückgabe der verwendeten Ressourcen. Sie wird vom Web-Container einmalig aufgerufen. Danach wird die Anfrage nicht mehr über doFilter() verarbeitet.
Beispielcode - Servlet-Spezifikation
Beispielcode - @Component
- @Component: Filter kann als Spring Bean registriert werden.
- @Order: Wenn mehrere Filter vorhanden sind, kann die Reihenfolge festgelegt werden.
- Wenn ein Filter, der der Servlet-Spezifikation entspricht, auf diese Weise als Spring Bean registriert wird, können auch andere Beans verwendet werden, die der Spring-Spezifikation entsprechen.
Beispielcode - @Configuration
Wenn ein Filter nur für bestimmte URIs funktionieren soll, kann er mit FilterRegistrationBean als Spring Bean registriert werden.
Filter-Zweck
Filter sind hauptsächlich für die Validierung und Verarbeitung von Anfrageparametern zuständig.
- Allgemeine Aufgaben im Zusammenhang mit der Sicherheit
- Da Filter im Web-Container ausgeführt werden, können sie Sicherheitsüberprüfungen (z. B. XSS-, CSRF-Abwehr) durchführen und ungültige Anfragen blockieren. Da die Anfrage nicht an den Spring-Container weitergeleitet wird, sondern direkt blockiert wird, kann die Sicherheit weiter erhöht werden.
- Protokollierung aller Anfragen
- Komprimierung von Bildern/Daten und Zeichenkodierung
- Filter haben Funktionen implementiert, die in Webanwendungen allgemein verwendet werden, wie z. B. das Komprimieren von Bildern oder Daten und das Codieren von Zeichenketten.
- Anpassen von ServletRequest
- HttpServletRequest kann den Inhalt des Bodys nur einmal lesen. Daher können Filter oder Interceptors den Body nicht lesen. Ein benutzerdefiniertes ServletRequest kann erstellt werden, um den Body zu protokollieren.
Interceptor
Was ist ein Interceptor?
Im Gegensatz zu Filtern, die eine J2EE-Standard-Spezifikation sind, ist ein Interceptor eine Funktion, die von Spring bereitgestellt wird. Er ermöglicht es, auf Anfragen und Antworten vor und nach dem Aufruf des Controllers durch das Dispatcher Servlet zuzugreifen oder diese zu verarbeiten. Das heisst, im Gegensatz zu Filtern, die im Web-Container arbeiten, arbeitet der Interceptor im Spring-Kontext.
Das Dispatcher Servlet fordert über Handler-Mapping den entsprechenden Controller an. Als Ergebnis gibt es die Ausführungskette (HandlerExecutionChain) zurück. Wenn diese Ausführungskette mehr als einen Interceptor registriert hat, wird der Controller nacheinander über die Interceptors ausgeführt. Wenn keine Interceptors vorhanden sind, wird der Controller direkt ausgeführt.
Interceptor-Implementierung
Um einen Interceptor hinzuzufügen, muss das HandlerInterceptor-Interface von org.springframework.web.servlet implementiert werden. Dieses Interface verfügt über die folgenden drei Methoden.
- preHandle-Methode
- Die preHandle-Methode wird vor dem Aufruf des Controllers ausgeführt. Daher kann sie verwendet werden, um Vorverarbeitungsaufgaben vor dem Controller durchzuführen oder Anforderungsinformationen zu verarbeiten oder hinzuzufügen.
- Der dritte Parameter der preHandle-Methode, der Handler-Parameter, ist ein Objekt, das die Informationen der Methode mit @RequestMapping abstrahiert.
- Der Rückgabetyp der preHandle-Methode ist boolean. Wenn der Rückgabewert true ist, wird mit dem nächsten Schritt fortgefahren. Andernfalls wird die Verarbeitung abgebrochen und die nachfolgenden Aufgaben (nächster Interceptor oder Controller) werden nicht ausgeführt.
- postHandle-Methode
- Die postHandle-Methode wird nach dem Aufruf des Controllers ausgeführt. Daher kann sie verwendet werden, wenn es Nachverarbeitungsaufgaben nach dem Controller gibt.
- afterCompletion-Methode
- Die afterCompletion-Methode wird, wie der Name schon sagt, nach Abschluss aller Aufgaben ausgeführt, einschliesslich der Erstellung des endgültigen Ergebnisses durch alle Views.
Beispielcode
- Der erstellte Interceptor wird als Bean registriert.
- Der erstellte Interceptor wird in der addInterceptors()-Methode des WebMvcConfigurer-Interfaces registriert.
- Interceptors werden in der Reihenfolge ausgeführt, in der sie im InterceptorRegistry registriert wurden.
Interceptor-Zweck
Interceptors sind hauptsächlich für die Verarbeitung der Integrität von Anforderungsinformationen unter Verwendung der Service-Logik zuständig.
- Allgemeine Aufgaben wie Authentifizierung/Autorisierung
- Sie können beispielsweise Aufgaben im Zusammenhang mit der Authentifizierung oder Autorisierung überprüfen, bevor sie an den Controller weitergeleitet werden.
- Protokollierung von API-Aufrufen
- Über die empfangenen HttpServletRequest- und HttpServletResponse-Objekte können Informationen zum Client aufgezeichnet werden.
- Verarbeitung der Daten, die an den Controller übergeben werden
- Die empfangenen HttpServletRequest- und HttpServletResponse-Objekte können verarbeitet und an den Controller übergeben werden.
- AOP-Simulation
- Über den dritten Parameter der preHandle()-Methode, HandlerMethod, können zusätzliche Informationen wie die Signatur der auszuführenden Methode ermittelt werden, um zu entscheiden, ob die Logik ausgeführt werden soll.
Filter vs. Interceptor
- Filter werden im Web-Kontext ausgeführt, während Interceptors im Spring-Kontext ausgeführt werden, d. h. der Ausführungszeitpunkt ist unterschiedlich.
- Filter können vor und nach dem Dispatcher Servlet verwendet werden, während Interceptors vor und nach dem Controller verwendet werden können.
- Filter werden in der Regel verwendet, wenn Aufgaben unabhängig von Spring global verarbeitet werden müssen, wenn die Parameter selbst validiert werden müssen oder wenn anstelle von HttpServletRequest ServletRequest verwendet wird.
- Interceptors werden in der Regel verwendet, wenn Aufgaben global verarbeitet werden müssen, die mit den Anfragen des Clients im Spring-Bereich zusammenhängen, oder wenn Service-Logik einbezogen werden muss.
- Interceptors können mit @ControllerAdvice und @ExceptionHandler zur Ausnahmebehandlung verwendet werden, Filter hingegen nicht.
- Filter behandeln Ausnahmen, die an dieser Stelle auftreten, in der Regel durch Einbetten der doFilter()-Methode in einen try-catch-Block.
Argument Resolver
Was ist ein Argument Resolver?
Ein Argument Resolver kann indirekt dazu beitragen, ein gewünschtes Objekt aus dem Wert einer Anfrage zu erstellen, wenn eine Anfrage an einen Controller gesendet wird.
Zweck des Argument Resolvers
Angenommen, eine Anfrage mit einem JWT-Token wird gesendet. Wir müssen den Token auf seine Gültigkeit überprüfen und anschliessend die in dem Token gespeicherte ID extrahieren, um ein Login-Benutzerobjekt zu erstellen.
Wenn kein Argument Resolver verwendet wird, muss dieser Validierungs- und Konvertierungsprozess in jedes einzelne Controller implementiert werden. Dies führt zu redundantem Code in Controllern, die eine Benutzerüberprüfung benötigen, und erhöht die Verantwortung des Controllers. Ein Argument Resolver kann dieses Problem lösen.
Implementierung des Argument Resolvers
Ein Argument Resolver kann durch Implementierung von HandlerMethodArgumentResolver verwendet werden. Dieses Interface gibt vor, dass die folgenden beiden Methoden implementiert werden müssen.
- supportsParameter-Methode
- Eine bestimmte Annotation wird vor dem Parameter platziert, für den der Argument Resolver ausgeführt werden soll. Die supportsParameter()-Methode überprüft, ob die angeforderte Methode über die gewünschte Annotation verfügt. Wenn die angeforderte Methode die gewünschte Annotation enthält, wird true zurückgegeben.
- resolveArgument-Methode
- Wenn supportsParameter true zurückgibt, d. h. wenn eine Methode mit einer bestimmten Annotation vorhanden ist, ist dies die Methode, die den Parameter in das gewünschte Format bindet und zurückgibt.
Wenn der Argument Resolver auf diese Weise verwendet wird, sieht die Implementierung des Controllers wie folgt aus:
Unterschiede zwischen Argument Resolver und Interceptor
- Argument Resolver wird nach dem Interceptor ausgeführt und gibt ein gewünschtes Objekt aus dem Wert einer Anfrage zurück, wenn eine Anfrage an einen Controller gesendet wird.
- Im Gegensatz dazu fängt der Interceptor die Anfrage vor der tatsächlichen Ausführung des Controllers ab und kann kein bestimmtes Objekt zurückgeben. Es gibt nur die Rückgabetypen boolean oder void.
Quellen
- https://mangkyu.tistory.com/173
- https://junhyunny.github.io/spring-boot/filter-interceptor-and-aop/
- https://supawer0728.github.io/2018/04/04/spring-filter-interceptor/
- https://tecoble.techcourse.co.kr/post/2021-05-24-spring-interceptor/
- https://baeldung-cn.com/spring-mvc-handlerinterceptor-vs-filter
- https://www.baeldung.com/spring-boot-add-filter
Voraussichtliche Interviewfragen und Antworten
Was ist ein Filter?
Ein Filter ist eine Funktion, die vor/nach der Weiterleitung einer Anfrage an das Dispatcher Servlet zusätzliche Aufgaben für alle Anfragen zu einem bestimmten URL-Muster verarbeiten kann und auf der Ebene des Servlet-Containers ausgeführt wird.
Wann wird ein Filter verwendet?
Filter können verwendet werden, um Aufgaben zu verarbeiten, die unabhängig von Spring global verarbeitet werden müssen. Oder sie werden verwendet, um Anforderungsparameter zu validieren.
Hauptsächlich werden allgemeine Aufgaben im Zusammenhang mit der Sicherheit, die Protokollierung aller Anfragen, die Komprimierung von Bildern/Daten und die Zeichenkodierung sowie das Anpassen von ServletRequest verarbeitet.
Was ist ein Interceptor?
Ein Interceptor ist eine Funktion, die es ermöglicht, auf Anfragen und Antworten vor und nach dem Aufruf des Controllers durch das Dispatcher Servlet zuzugreifen oder diese zu verarbeiten und auf der Ebene des Spring-Containers ausgeführt wird.
Wann wird ein Interceptor verwendet?
Interceptors können verwendet werden, um Aufgaben zu verarbeiten, die global mit den Anfragen des Clients zusammenhängen, und werden hauptsächlich verwendet, wenn bei der Validierung Service-Logik aufgerufen wird.
Hauptsächlich werden allgemeine Aufgaben wie Authentifizierung/Autorisierung, die Protokollierung von API-Aufrufen und die Verarbeitung der Daten, die an den Controller übergeben werden, verarbeitet.
Was ist der Unterschied zwischen Filter und Interceptor?
Filter werden auf der Ebene des Servlet-Containers ausgeführt, während Interceptors auf der Ebene des Spring-Containers ausgeführt werden.
Filter können vor und nach dem Dispatcher Servlet verwendet werden, während Interceptors vor und nach dem Controller verwendet werden können.
Daher ist es ratsam, Filter zu verwenden, wenn Aufgaben unabhängig von Spring global verarbeitet werden müssen, und Interceptors, wenn Aufgaben global verarbeitet werden müssen, die mit den Anfragen des Clients zusammenhängen.
Was ist ein Argument Resolver?
Ein Argument Resolver ist eine Funktion, die indirekt dazu beiträgt, ein gewünschtes Objekt aus dem Wert einer Anfrage zu erstellen, wenn eine Anfrage an einen Controller gesendet wird.
Wann wird ein Argument Resolver verwendet?
Wenn eine Anfrage mit einem JWT-Token gesendet wird, kann ein Argument Resolver verwendet werden, um den Token auf seine Gültigkeit zu überprüfen und anschliessend die in dem Token gespeicherte ID zu extrahieren, um ein LoginMember-Objekt zu erstellen.
Was ist der Unterschied zwischen Interceptor und Argument Resolver?
Ein Argument Resolver gibt ein gewünschtes Objekt aus dem Wert einer Anfrage zurück, wenn eine Anfrage an einen Controller gesendet wird. Ein Interceptor kann hingegen kein Objekt zurückgeben. Ein Argument Resolver wird nach der Ausführung des Interceptors ausgeführt.
Kommentare0