![translation](https://cdn.durumis.com/common/trans.png)
To jest post przetłumaczony przez AI.
Wybierz język
Tekst podsumowany przez sztuczną inteligencję durumis
- Filtry to funkcja określona w standardzie J2EE, która pozwala na przetwarzanie dodatkowych zadań dla wszystkich żądań pasujących do wzorca URL przed lub po przekazaniu ich do dyspozytora serwletów. Funkcja ta działa w kontenerze webowym. Interseptory to technologia dostarczana przez Springa, która pozwala na odwoływanie się do żądań i odpowiedzi, a także na ich przetwarzanie przed i po wywołaniu kontrolera przez dyspozytora serwletów. Interseptory działają w kontekście Springa.
- Rozdzielacz argumentów może pośrednio tworzyć pożądane obiekty z wartości wprowadzonych z żądaniem, gdy dociera ono do kontrolera.
- Różnica między filtrami i interseptami polega na tym, gdzie działają (w kontenerze webowym czy w kontenerze Springa), a także na tym, czy przetwarzają żądania względem dyspozytora serwletów czy kontrolera. Rozdzielacze argumentów działają po interseptach i zwracają określony obiekt.
Co to jest filtr (Filter)?
Filtr jest funkcją zgodną ze standardem J2EE, która umożliwia wykonywanie dodatkowych operacji dla wszystkich żądań zgodnych z wzorcem adresu URL przed i po przekazaniu żądania do serwletu rozsyłającego (Dispatcher Servlet). Oznacza to, że jest zarządzany przez kontener WWW, taki jak Tomcat, a nie przez kontener Springa, więc obsługuje żądania przed dotarciem do serwletu rozsyłającego.
Implementacja filtra (Filter)
Aby dodać filtr, należy zaimplementować interfejs Filter z javax.servlet, który zawiera trzy metody:
- Metoda init
- Metoda ta służy do zainicjowania obiektu filtra i dodania go do usługi. Kontener WWW wywołuje metodę init tylko raz, aby zainicjować obiekt filtra, a następnie wszystkie następne żądania są obsługiwane za pomocą metody doFilter().
- Metoda doFilter
- Metoda ta jest wywoływana przez kontener WWW przed przekazaniem wszystkich żądań HTTP zgodnych z wzorcem adresu URL do serwletu rozsyłającego, a także przed wysłaniem odpowiedzi HTTP z serwletu rozsyłającego do klienta.
DoFilter() przyjmuje jako parametr FilterChain, który służy do przekazywania żądania do następnego celu za pomocą doFilter() łańcucha. Wstawiając wymagany proces przed i po chain.doFilter(), możemy wykonać pożądane operacje.
- Metoda ta jest wywoływana przez kontener WWW przed przekazaniem wszystkich żądań HTTP zgodnych z wzorcem adresu URL do serwletu rozsyłającego, a także przed wysłaniem odpowiedzi HTTP z serwletu rozsyłającego do klienta.
- Metoda destory
- Metoda ta służy do usunięcia obiektu filtra z usługi i zwolnienia używanych zasobów. Jest wywoływana tylko raz przez kontener WWW, a po tym żądania nie są już obsługiwane za pomocą doFilter().
Przykładowy kod - specyfikacja Servlet
@WebFilter("/*")
public class dolphagoFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// Przed przetworzeniem
request.setCharacterEncoding("UTF-8");
System.out.println("Przed doFilter()...");
filterChain.doFilter(request, response);
// Po przetworzeniu
System.out.println("Po doFilter()...");
}
@Override
public void destroy() { }
Przykładowy kod - @Component
@Order(1)
@Component
public class CustomFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() { }
- @Component: Umożliwia zarejestrowanie filtra jako fasoli Springa.
- @Order: Umożliwia określenie kolejności, gdy jest wiele filtrów.
- Rejestrując filtr zgodny ze specyfikacją Servlet jako fasolę Springa w ten sposób, można korzystać z innych fasoli zgodnych ze specyfikacją Springa.
Przykładowy kod - @Configuration
@Configuration
public class CustomRegistrationBean {
@Bean
public FilterRegistrationBean customFilterBean() {
FilterRegistrationBean registration = new FilterRegistrationBean<>();
registration.setFilter(new CustomFilter());
registration.setOrder(1);
registration.addUrlPatterns("/api/*");
return registration;
}
Jeśli chcesz, aby filtr działał tylko dla konkretnego URI, możesz zarejestrować filtr jako fasolę Springa za pomocą FilterRegistrationBean.
Zastosowanie filtra (Filter)
Głównie odpowiada za weryfikację i przetwarzanie samych parametrów żądania.
- Wspólne zadania związane z bezpieczeństwem
- Filtry działają w kontenerze WWW, dlatego można przeprowadzić kontrolę bezpieczeństwa (np. ochrona przed XSS, CSRF), aby zablokować nieprawidłowe żądania. Ponieważ żądanie nie dociera do kontenera Springa, a jedynie zostaje zablokowane, zwiększa to bezpieczeństwo.
- Rejestrowanie wszystkich żądań
- Kompresja obrazów/danych i kodowanie znaków
- Filtry zaimplementowały funkcje używane w całej aplikacji internetowej, takie jak kompresja obrazów lub danych lub kodowanie znaków.
- Dostosowywanie żądania ServletRequest
- HttpServletRequest może odczytać zawartość Body tylko raz. Dlatego filtr lub przechwytywacz nie mogą odczytać Body. Aby rejestrować Body, można utworzyć niestandardowe żądanie ServletRequest.
Przechwytywacz (Interceptor)
Co to jest przechwytywacz (Interceptor)?
Przechwytywacz (Interceptor) w odróżnieniu od filtra (Filter), który jest zgodny ze standardem J2EE, jest technologią dostarczaną przez Springa, która umożliwia dostęp do żądania i odpowiedzi lub ich przetwarzanie przed i po wywołaniu kontrolera przez serwlet rozsyłający. Innymi słowy, w przeciwieństwie do filtra, który działa w kontenerze WWW, przechwytywacz działa w kontekście Springa.
Serwlet rozsyłający żąda, aby dopasowanie obsługi wywołało odpowiedni kontroler, co skutkuje zwróceniem łańcucha wykonania (HandlerExecutionChain). Ten łańcuch wykonania zawiera zarejestrowane przechwytywacze, więc przechodzi przez nie kolejno, aż dojdzie do wykonania kontrolera, a jeśli nie ma przechwytywaczy, kontroler jest wykonywany bezpośrednio.
Implementacja przechwytywacza (Interceptor)
Aby dodać przechwytywacz, należy zaimplementować interfejs org.springframework.web.servlet.HandlerInterceptor, który zawiera trzy metody:
- Metoda preHandle
- Metoda preHandle jest wykonywana przed wywołaniem kontrolera. W związku z tym może być używana do wykonywania operacji przed przetworzeniem lub do modyfikowania lub dodawania informacji o żądaniu.
- Trzeci parametr metody preHandle, parametr handler, to obiekt, który abstrakcyjnie reprezentuje informacje o metodzie oznaczonej @RequestMapping.
- Typ zwracany przez metodę preHandle to boolean, a wartość zwracana true oznacza, że przechodzi do następnego kroku, ale jeśli jest to false, praca jest przerywana i następne operacje (następny przechwytywacz lub kontroler) nie są wykonywane.
- Metoda postHandle
- Metoda postHandle jest wykonywana po wywołaniu kontrolera. W związku z tym może być używana do wykonywania operacji po przetworzeniu.
- Metoda afterCompletion
- Metoda afterCompletion, jak sama nazwa wskazuje, jest wykonywana po zakończeniu wszystkich operacji, w tym tworzenia ostatecznego wyniku przez wszystkie widoki.
Przykładowy kod
@Component
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor());
registry.addInterceptor(new LoggingInterceptor());
}
- Zarejestruj utworzony przechwytywacz jako fasolę.
- Zarejestruj utworzony przechwytywacz w metodzie addInterceptors() interfejsu WebMvcConfigurer.
- Przechwytywacze działają w kolejności, w jakiej zostały zarejestrowane w InterceptorRegistry.
Zastosowanie przechwytywacza (Interceptor)
Głównie odpowiada za przetwarzanie spójności informacji o żądaniu przy użyciu logiki usług.
- Wspólne zadania, takie jak uwierzytelnianie/autoryzacja
- Na przykład można sprawdzić zadania związane z żądaniem klienta, takie jak uwierzytelnianie lub autoryzacja, przed przekazaniem ich do kontrolera.
- Rejestrowanie wywołań API
- Można rejestrować informacje o kliencie za pomocą przekazywanych obiektów HttpServletRequest i HttpServletResponse.
- Przetwarzanie danych przekazywanych do kontrolera
- Można modyfikować przekazywane obiekty HttpServletRequest i HttpServletResponse i przekazywać je do kontrolera.
- Naśladowanie AOP
- Można zidentyfikować sygnaturę wykonywanej metody i inne dodatkowe informacje za pomocą HandlerMethod, trzeciego parametru metody preHandle(), aby określić, czy należy wykonać logikę.
Filtr (Filter) vs Przechwytywacz (Interceptor)
- Filtr działa w kontekście WWW, a przechwytywacz działa w kontekście Springa, więc różnią się momentem wykonania.
- Filtr może obsługiwać okresy przed i po serwlecie rozsyłającym, a przechwytywacz może obsługiwać okresy przed i po kontrolerze.
- Filtr najlepiej nadaje się do wykonywania zadań globalnych niezwiązanych ze Springiem, weryfikacji samych parametrów wejściowych lub używania obiektu ServletRequest zamiast HttpServletRequest.
- Przechwytywacz najlepiej nadaje się do wykonywania zadań globalnych związanych z żądaniem klienta, które weszły do Springa, lub do mieszania logiki usług.
- Przechwytywacz umożliwia obsługę wyjątków przy użyciu @ControllerAdvice i @ExceptionHandler, ale filtr nie może używać ich do obsługi wyjątków.
- Filtr zazwyczaj otacza metodę doFilter() blokiem try~catch, aby obsługiwać wyjątki, które pojawiają się w tym momencie.
Rozdzielacz argumentów
Co to jest rozdzielacz argumentów?
Rozdzielacz argumentów pośrednio pomaga tworzyć pożądane obiekty z wartości otrzymanych w żądaniu, gdy żądanie dociera do kontrolera.
Zastosowanie rozdzielacza argumentów
Załóżmy na przykład, że żądanie przychodzi wraz z tokenem JWT. Musimy zweryfikować, czy ten token jest ważny, a następnie wyodrębnić identyfikator zapisany w tokenie i utworzyć obiekt zalogowanego użytkownika.
W takim przypadku, jeśli nie użyjesz rozdzielacza argumentów, będziesz musiał zaimplementować proces weryfikacji tokenu i konwersji na obiekt zalogowanego użytkownika w każdym kontrolerze. W rezultacie w kontrolerach, które wymagają weryfikacji użytkownika, pojawi się kod duplikacyjny, a odpowiedzialność kontrolera wzrośnie. Rozdzielacz argumentów może rozwiązać ten problem.
Implementacja rozdzielacza argumentów
Rozdzielacz argumentów można użyć implementując HandlerMethodArgumentResolver. Ten interfejs wymaga implementacji dwóch metod:
boolean supportsParameter(MethodParameter parameter);
@Nullable
- Metoda supportsParameter
- Utwórz i dołącz określona adnotację przed parametrem, dla którego chcesz, aby rozdzielacz argumentów był uruchomiony. Metoda supportsParameter() sprawdza, czy żądany parametr metody zawiera pożądaną adnotację, a jeśli tak, zwraca true.
- Metoda resolveArgument
- Jeśli w supportsParameter otrzymano true, tzn. jeśli istnieje jakaś metoda z dołączoną określoną adnotacją, jest to metoda, która wiąże informacje w żądanym formacie i zwraca je jako parametr.
Implementacja kontrolera przy użyciu rozdzielacza argumentów wygląda następująco:
@GetMapping("/me")
public ResponseEntity findMemberOfMine(@AuthenticationPrincipal LoginMember loginMember) {
MemberResponse memberResponse = memberService.findMember(loginMember.getId());
return ResponseEntity.ok().body(memberResponse);
Różnica między rozdzielaczem argumentów a przechwytywaczem (Interceptor)
- Rozdzielacz argumentów działa po przechwytywaczu, a gdy żądanie dociera do kontrolera, zwraca pożądany obiekt na podstawie wartości otrzymanej w żądaniu.
- Przechwytywacz z kolei przechwytuje żądanie przed rzeczywistym wykonaniem kontrolera i nie może zwrócić żadnego konkretnego obiektu. Istnieje tylko typ zwracany boolean lub void.
Źródło
- 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
Przewidywane pytania i odpowiedzi na rozmowę kwalifikacyjną
Co to jest filtr?
Filtr umożliwia wykonywanie dodatkowych operacji dla wszystkich żądań zgodnych z wzorcem adresu URL przed i po przekazaniu żądania do serwletu rozsyłającego. Działa w kontenerze Servlet.
Kiedy używać filtra?
Filtry można wykorzystać do wykonywania zadań globalnych niezwiązanych ze Springiem. Mogą być również używane do weryfikacji samych parametrów żądania.
Typowe przykłady to zadania związane z bezpieczeństwem, rejestrowanie wszystkich żądań, kompresja obrazów/danych i kodowanie znaków, dostosowywanie żądania ServletRequest.
Co to jest przechwytywacz?
Przechwytywacz umożliwia dostęp do żądania i odpowiedzi lub ich przetwarzanie przed i po wywołaniu kontrolera przez serwlet rozsyłający. Działa w kontenerze Springa.
Kiedy używać przechwytywacza?
Przechwytywacze można wykorzystać do wykonywania zadań globalnych związanych z żądaniem klienta, które weszły do Springa. Mogą być również używane do weryfikacji, która obejmuje wywołanie logiki usług.
Typowe przykłady to zadania związane z uwierzytelnianiem/autoryzacją, rejestrowanie wywołań API, przetwarzanie danych przekazywanych do kontrolera.
Jaka jest różnica między filtrem a przechwytywaczem?
Filtr działa w kontenerze Servlet, a przechwytywacz działa w kontenerze Springa.
Filtr może obsługiwać okresy przed i po serwlecie rozsyłającym, a przechwytywacz może obsługiwać okresy przed i po kontrolerze.
Dlatego filtr najlepiej nadaje się do wykonywania zadań globalnych niezwiązanych ze Springiem, a przechwytywacz najlepiej nadaje się do wykonywania zadań globalnych związanych z żądaniem klienta, które weszły do Springa.
Co to jest rozdzielacz argumentów?
Rozdzielacz argumentów pośrednio pomaga tworzyć pożądane obiekty z wartości otrzymanych w żądaniu, gdy żądanie dociera do kontrolera.
Kiedy używać rozdzielacza argumentów?
Można go użyć na przykład, gdy żądanie przychodzi wraz z tokenem JWT, aby zweryfikować, czy token jest ważny, a następnie wyodrębnić identyfikator zapisany w tokenie i utworzyć obiekt LoginMember.
Jaka jest różnica między przechwytywaczem a rozdzielaczem argumentów?
Rozdzielacz argumentów działa po przechwytywaczu, a gdy żądanie dociera do kontrolera, zwraca pożądany obiekt na podstawie wartości otrzymanej w żądaniu. Przechwytywacz z kolei nie może zwrócić żadnego konkretnego obiektu.