![translation](https://cdn.durumis.com/common/trans.png)
Esta es una publicación traducida por IA.
[Spring] ¿Qué son Filter, Interceptor y Argument Resolver?
- Idioma de escritura: Coreano
- •
-
País de referencia: Todos los países
- •
- Tecnología de la información
Seleccionar idioma
Texto resumido por la IA durumis
- Filter es una función de especificación estándar de J2EE que proporciona la capacidad de procesar tareas adicionales para todas las solicitudes que coincidan con un patrón de URL antes o después de que una solicitud se envíe al servlet de despacho. Funciona en el contenedor web, mientras que Interceptor es una tecnología proporcionada por Spring que proporciona la capacidad de hacer referencia o procesar solicitudes y respuestas antes y después de que el servlet de despacho llame al controlador. Funciona en el contexto de Spring.
- Argument Resolver puede ayudarte indirectamente a crear el objeto deseado a partir del valor que ingresa a la solicitud cuando entra una solicitud al controlador.
- Filter e Interceptor difieren en si funcionan en el contenedor de Spring o en el contenedor web, si procesan la solicitud con referencia al servlet de despacho o al controlador, y Argument Resolver funciona después de Interceptor y devuelve un objeto específico.
¿Qué es un filtro (Filter)?
Un filtro es una función de la especificación estándar de J2EE que permite procesar trabajos adicionales para todas las solicitudes que coincidan con un patrón de URL, antes o después de que la solicitud se transfiera al servlet de despacho (Dispatcher Servlet). En otras palabras, se gestiona mediante el contenedor web, como Tomcat, en lugar del contenedor Spring, por lo que procesa las solicitudes antes de que lleguen al servlet de despacho.
Implementación del filtro (Filter)
Para agregar un filtro, debe implementar la interfaz Filter de javax.servlet, que tiene los siguientes tres métodos.
- Método init
- Este es un método para inicializar el objeto de filtro y agregarlo al servicio. Cuando el contenedor web llama al método init una vez para inicializar el objeto de filtro, las solicitudes posteriores se procesan a través del método doFilter().
- Método doFilter
- Este método se ejecuta antes de que todas las solicitudes HTTP que coincidan con el patrón de URL se transfieran al servlet de despacho y después de que el servlet de despacho envíe la respuesta HTTP al cliente.
El método doFilter() tiene un parámetro FilterChain, que se usa para enviar la solicitud al siguiente destino a través del método doFilter() de FilterChain. Se pueden agregar procesos necesarios antes y después de chain.doFilter(), lo que le permite realizar el procesamiento deseado.
- Este método se ejecuta antes de que todas las solicitudes HTTP que coincidan con el patrón de URL se transfieran al servlet de despacho y después de que el servlet de despacho envíe la respuesta HTTP al cliente.
- Método destory
- Este es un método para eliminar el objeto de filtro del servicio y devolver los recursos utilizados. Se llama una vez por el contenedor web y después de eso, ya no se procesa por doFilter().
Código de ejemplo - Especificación 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 {
//Preprocesamiento aquí
request.setCharacterEncoding("UTF-8");
System.out.println("Antes de doFilter()...");
filterChain.doFilter(request, response);
//Postprocesamiento aquí
System.out.println("Después de doFilter()...");
}
@Override
public void destroy() { }
Código de ejemplo - @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: Se puede registrar el filtro como un bean de Spring.
- @Order: Puede establecer el orden si hay varios filtros.
- Si registra el filtro correspondiente a la especificación del servlet como un bean de Spring, puede utilizar otros beans correspondientes a la especificación de Spring.
Código de ejemplo - @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;
}
Si desea que el filtro solo funcione para una URI específica, puede registrar el filtro como un bean de Spring usando FilterRegistrationBean.
Usos del filtro (Filter)
Principalmente se encarga de la validación y el procesamiento de los propios parámetros de la solicitud.
- Trabajos comunes relacionados con la seguridad
- Dado que el filtro opera en el contenedor web, puede realizar comprobaciones de seguridad (XSS, defensa CSRF, etc.) y bloquear las solicitudes incorrectas. Dado que la solicitud no se transfiere al contenedor Spring, puede aumentar la seguridad.
- Registro de todas las solicitudes
- Compresión de imágenes/datos y codificación de cadenas
- El filtro implementó funciones que se usan ampliamente en las aplicaciones web, como la compresión de imágenes o datos y la codificación de cadenas.
- Personalización de ServletRequest
- HttpServletRequest solo puede leer el contenido del Body una vez. Por lo tanto, Filter o Interceptor no pueden leer el Body. Se puede crear un ServletRequest personalizado para registrar el Body.
Interceptor (Interceptor)
¿Qué es un Interceptor (Interceptor)?
A diferencia de Filter (Filter), que es una especificación estándar de J2EE, un Interceptor (Interceptor) es una tecnología proporcionada por Spring que permite consultar o procesar solicitudes y respuestas antes y después de que el servlet de despacho llame al controlador. En otras palabras, a diferencia de los filtros que funcionan en el contenedor web, los interceptores funcionan en el contexto de Spring.
El servlet de despacho solicita al mapeo del controlador que encuentre el controlador apropiado. Como resultado, devuelve la cadena de ejecución (HandlerExecutionChain). Entonces, esta cadena de ejecución, si se registra más de un interceptor, ejecuta secuencialmente el interceptor y ejecuta el controlador. Si no hay interceptores, ejecuta el controlador inmediatamente.
Implementación del Interceptor (Interceptor)
Para agregar un interceptor, debe implementar la interfaz org.springframework.web.servlet.HandlerInterceptor, que tiene los siguientes tres métodos.
- Método preHandle
- El método preHandle se ejecuta antes de que se llame al controlador. Por lo tanto, se puede utilizar para trabajos de preprocesamiento que deben procesarse antes del controlador o para procesar o agregar información de solicitud.
- El parámetro handler del tercer parámetro del método preHandle es un objeto que abstrae la información del método anotado con @RequestMapping.
- El tipo de retorno del método preHandle es boolean. Si el valor de retorno es true, continúa al siguiente paso, pero si es false, el trabajo se detiene y el trabajo posterior (el siguiente interceptor o controlador) no continúa.
- Método postHandle
- El método postHandle se ejecuta después de que se llama al controlador. Por lo tanto, se puede usar si hay algún trabajo de postprocesamiento que deba realizarse después del controlador.
- Método afterCompletion
- El método afterCompletion se ejecuta, como su nombre lo indica, después de que se completan todas las tareas, incluida la creación del resultado final en todas las vistas.
Código de ejemplo
@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());
}
- Registra el interceptor creado como un bean.
- Registra el interceptor creado en el método addInterceptors() de la interfaz WebMvcConfigurer.
- Los interceptores funcionan en el orden en que se registran en InterceptorRegistry.
Usos del Interceptor (Interceptor)
Principalmente se encarga de procesar la coherencia de la información de la solicitud utilizando la lógica del servicio.
- Trabajos comunes como la autenticación/autorización
- Como ejemplo, puede verificar trabajos relacionados con el cliente, como la autenticación o la autorización, antes de que se transfieran al controlador.
- Registro de llamadas a API
- Puede registrar la información del cliente a través de los objetos HttpServletRequest y HttpServletResponse que recibe.
- Procesamiento de datos que se transferirán al Controller
- Puede procesar los objetos HttpServletRequest y HttpServletResponse recibidos y transferirlos al controlador.
- Imitación de AOP
- Puede determinar si se ejecuta la lógica al consultar el método que se ejecutará, como la firma del método, a través del tercer parámetro HandlerMethod del método preHandle().
Filter (Filter) vs Interceptor (Interceptor)
- El filtro se ejecuta en el contexto web y el interceptor se ejecuta en el contexto de Spring, por lo que los tiempos de ejecución son diferentes.
- El filtro puede manejar antes y después del servlet de despacho, mientras que el interceptor puede manejar antes y después del controlador.
- El filtro es mejor para trabajos que deben procesarse globalmente independientemente de Spring, o para validar el propio parámetro de entrada, o cuando se usa ServletRequest en lugar de HttpServletRequest.
- El interceptor es mejor usar cuando se necesita procesar globalmente algo relacionado con la solicitud del cliente que ha ingresado en la unidad Spring o cuando necesita mezclar la lógica del servicio.
- El interceptor puede manejar excepciones usando @ControllerAdvice y @ExceptionHandler, pero el filtro no puede usar esto para manejar excepciones.
- El filtro generalmente maneja las excepciones que ocurren en ese momento envolviendo el método doFilter() con una instrucción try~catch.
Argument Resolver
¿Qué es Argument Resolver?
Argument Resolver puede ayudarte indirectamente a crear el objeto deseado a partir del valor que entra en el controlador cuando llega una solicitud.
Usos de Argument Resolver
Por ejemplo, supongamos que una solicitud llega con un token JWT. Necesitamos verificar si el token es válido y luego extraer el id almacenado en el token y crear un objeto de usuario de inicio de sesión.
En este caso, si no se utiliza Argument Resolver, se debe implementar el proceso de verificación del token y la conversión al objeto de usuario de inicio de sesión en cada controlador. Esto resultará en código duplicado en los controladores que requieren verificación de usuario y aumentará la responsabilidad de los controladores. Argument Resolver puede resolver este problema.
Implementación de Argument Resolver
Se puede utilizar ArgumentResolver implementando HandlerMethodArgumentResolver. Y esta interfaz especifica que se deben implementar los dos métodos siguientes.
boolean supportsParameter(MethodParameter parameter);
@Nullable
- Método supportsParameter
- Crea una anotación específica y la adjunta al parámetro del método que desea ejecutar ArgumentResolver. El método supportsParameter() verifica si la anotación deseada está adjunta al parámetro del método que se solicita y devuelve true si contiene la anotación deseada.
- Método resolveArgument
- Este es el método que vincula y devuelve la información en el formato deseado del parámetro si se recibe true en supportsParameter, es decir, si hay algún método con una anotación específica adjunta.
La implementación del controlador cuando se utiliza Argument Resolver es la siguiente.
@GetMapping("/me")
public ResponseEntity findMemberOfMine(@AuthenticationPrincipal LoginMember loginMember) {
MemberResponse memberResponse = memberService.findMember(loginMember.getId());
return ResponseEntity.ok().body(memberResponse);
Diferencias entre Argument Resolver e Interceptor (Interceptor)
- ArgumentResolver funciona después del interceptor y devuelve el objeto deseado a partir del valor que ingresa en el controlador cuando llega una solicitud.
- Por otro lado, el interceptor intercepta la solicitud antes de que se ejecute realmente el controlador y no puede devolver un objeto específico. Solo existen los tipos de retorno boolean o void.
Fuentes
- 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
Preguntas de la entrevista esperadas y respuestas
¿Qué es un filtro?
Un filtro es una función que permite procesar trabajos adicionales para todas las solicitudes que coincidan con un patrón de URL antes o después de que la solicitud se transfiera al servlet de despacho. Funciona en la unidad del contenedor de servlets.
¿Cuándo se utiliza un filtro?
Los filtros pueden usarse para procesar trabajos que deben procesarse globalmente independientemente de Spring. O también se utilizan para verificar los parámetros de la solicitud.
Principalmente se encarga de trabajos comunes relacionados con la seguridad, el registro de todas las solicitudes, la compresión de imágenes/datos y la codificación de cadenas, y la personalización de ServletRequest.
¿Qué es un interceptor?
Un interceptor es una función que permite consultar o procesar solicitudes y respuestas antes y después de que el servlet de despacho llame al controlador. En otras palabras, funciona en la unidad del contenedor de Spring.
¿Cuándo se utiliza un interceptor?
Los interceptores pueden usarse para procesar trabajos que deben procesarse globalmente que estén relacionados con la solicitud del cliente. También se utilizan cuando se necesita llamar a la lógica del servicio durante la verificación.
Principalmente se encarga de trabajos comunes como la autenticación/autorización, el registro de llamadas a API y el procesamiento de datos que se transferirán al Controller.
¿Cuál es la diferencia entre un filtro y un interceptor?
El filtro se ejecuta en la unidad del contenedor de servlets y el interceptor se ejecuta en la unidad del contenedor de Spring.
El filtro puede manejar antes y después del servlet de despacho, mientras que el interceptor puede manejar antes y después del controlador.
Por lo tanto, el filtro es mejor para realizar trabajos que deben procesarse globalmente independientemente de Spring. El interceptor es mejor para realizar trabajos que deben procesarse globalmente que estén relacionados con la solicitud del cliente.
¿Qué es Argument Resolver?
Argument Resolver puede ayudarte indirectamente a crear el objeto deseado a partir del valor que entra en el controlador cuando llega una solicitud.
¿Cuándo se utiliza Argument Resolver?
Cuando llega una solicitud con un token JWT, puede utilizarse para verificar si el token es válido y luego extraer el id almacenado en el token y crear un objeto LoginMember.
¿Cuál es la diferencia entre un interceptor y Argument Resolver?
Argument Resolver devuelve el objeto deseado a partir del valor que ingresa en el controlador cuando llega una solicitud. Por otro lado, el interceptor no puede devolver un objeto de esa manera, y Argument Resolver se ejecuta después de que se ejecuta el interceptor.