java - handlerinterceptoradapter - Spring Boot Agregando Interceptores de Solicitud HTTP
spring rest controller interceptor (6)
¿Cuál es la forma correcta de agregar interceptores HttpRequest en la aplicación de arranque de primavera? Lo que quiero hacer es registrar solicitudes y respuestas para cada solicitud http.
La documentación de arranque de Spring no cubre este tema en absoluto. ( http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/ )
Encontré algunas muestras web sobre cómo hacer lo mismo con versiones anteriores de spring, pero funcionan con applicationcontext.xml. Por favor ayuda.
Como está utilizando Spring Boot, supongo que preferiría confiar en la configuración automática de Spring siempre que sea posible.
Para agregar una configuración personalizada adicional como sus interceptores, solo proporcione una configuración o bean de
WebMvcConfigurerAdapter
.
Aquí hay un ejemplo de una clase de configuración:
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Autowired
HandlerInterceptor yourInjectedInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(...)
...
registry.addInterceptor(getYourInterceptor());
registry.addInterceptor(yourInjectedInterceptor);
// next two should be avoid -- tightly coupled and not very testable
registry.addInterceptor(new YourInterceptor());
registry.addInterceptor(new HandlerInterceptor() {
...
});
}
}
NOTA: no anote esto con @EnableWebMvc, si desea mantener la configuración automática de Spring Boots para mvc .
Dado que todas las respuestas a esto hacen uso del adaptador WebMvcConfigurer abstract ahora en desuso en lugar de WebMvcInterface (como ya señaló @sebdooe), aquí hay un ejemplo mínimo de trabajo para una aplicación SpringBoot (2.1.4) con un Interceptor:
Minimal.java:
@SpringBootApplication
public class Minimal
{
public static void main(String[] args)
{
SpringApplication.run(Minimal.class, args);
}
}
MinimalController.java:
@RestController
@RequestMapping("/")
public class Controller
{
@GetMapping("/")
@ResponseBody
public ResponseEntity<String> getMinimal()
{
System.out.println("MINIMAL: GETMINIMAL()");
return new ResponseEntity<String>("returnstring", HttpStatus.OK);
}
}
Config.java:
@Configuration
public class Config implements WebMvcConfigurer
{
//@Autowired
//MinimalInterceptor minimalInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(new MinimalInterceptor());
}
}
MinimalInterceptor.java:
public class MinimalInterceptor extends HandlerInterceptorAdapter
{
@Override
public boolean preHandle(HttpServletRequest requestServlet, HttpServletResponse responseServlet, Object handler) throws Exception
{
System.out.println("MINIMAL: INTERCEPTOR PREHANDLE CALLED");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
{
System.out.println("MINIMAL: INTERCEPTOR POSTHANDLE CALLED");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception
{
System.out.println("MINIMAL: INTERCEPTOR AFTERCOMPLETION CALLED");
}
}
funciona como se anuncia
La salida te dará algo como:
> Task :Minimal.main()
. ____ _ __ _ _
/// / ___''_ __ _ _(_)_ __ __ _ / / / /
( ( )/___ | ''_ | ''_| | ''_ // _` | / / / /
/// ___)| |_)| | | | | || (_| | ) ) ) )
'' |____| .__|_| |_|_| |_/__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.4.RELEASE)
2019-04-29 11:53:47.560 INFO 4593 --- [ main] io.minimal.Minimal : Starting Minimal on y with PID 4593 (/x/y/z/spring-minimal/build/classes/java/main started by x in /x/y/z/spring-minimal)
2019-04-29 11:53:47.563 INFO 4593 --- [ main] io.minimal.Minimal : No active profile set, falling back to default profiles: default
2019-04-29 11:53:48.745 INFO 4593 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-04-29 11:53:48.780 INFO 4593 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-04-29 11:53:48.781 INFO 4593 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.17]
2019-04-29 11:53:48.892 INFO 4593 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-04-29 11:53:48.893 INFO 4593 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1269 ms
2019-04-29 11:53:49.130 INFO 4593 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService ''applicationTaskExecutor''
2019-04-29 11:53:49.375 INFO 4593 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''''
2019-04-29 11:53:49.380 INFO 4593 --- [ main] io.minimal.Minimal : Started Minimal in 2.525 seconds (JVM running for 2.9)
2019-04-29 11:54:01.267 INFO 4593 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet ''dispatcherServlet''
2019-04-29 11:54:01.267 INFO 4593 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet ''dispatcherServlet''
2019-04-29 11:54:01.286 INFO 4593 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 19 ms
MINIMAL: INTERCEPTOR PREHANDLE CALLED
MINIMAL: GETMINIMAL()
MINIMAL: INTERCEPTOR POSTHANDLE CALLED
MINIMAL: INTERCEPTOR AFTERCOMPLETION CALLED
Para agregar interceptor a una aplicación de arranque por resorte, haga lo siguiente
-
Crear una clase de interceptor
public class MyCustomInterceptor implements HandlerInterceptor{ //unimplemented methods comes here. Define the following method so that it //will handle the request before it is passed to the controller. @Override public boolean preHandle(HttpServletRequest request,HttpServletResponse response){ //your custom logic here. return true; } }
-
Definir una clase de configuración
@Configuration public class MyConfig extends WebMvcConfigurerAdapter{ @Override public void addInterceptors(InterceptorRegistry registry){ registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("/**"); } }
-
Eso es. Ahora todas sus solicitudes pasarán por la lógica definida en el método preHandle () de MyCustomInterceptor.
También puede considerar usar la biblioteca SpringSandwich de código abierto que le permite anotar directamente en sus controladores Spring Boot qué interceptores aplicar, de la misma manera que anota sus rutas de URL.
De esa manera, no hay cadenas propensas a errores tipográficos flotando: el método de SpringSandwich y las anotaciones de clase sobreviven fácilmente a la refactorización y dejan en claro qué se aplica dónde. (Divulgación: soy el autor).
Tuve el mismo problema de WebMvcConfigurerAdapter en desuso. Cuando busqué ejemplos, apenas encontré ningún código implementado. Aquí hay una pieza de código de trabajo.
crear una clase que extienda HandlerInterceptorAdapter
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import me.rajnarayanan.datatest.DataTestApplication;
@Component
public class EmployeeInterceptor extends HandlerInterceptorAdapter {
private static final Logger logger = LoggerFactory.getLogger(DataTestApplication.class);
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String x = request.getMethod();
logger.info(x + "intercepted");
return true;
}
}
luego implemente la interfaz WebMvcConfigurer
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import me.rajnarayanan.datatest.interceptor.EmployeeInterceptor;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
EmployeeInterceptor employeeInterceptor ;
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(employeeInterceptor).addPathPatterns("/employee");
}
}
WebMvcConfigurerAdapter
quedará en desuso con Spring 5. Desde su
Javadoc
:
@deprecated a partir de 5.0 {@link WebMvcConfigurer} tiene métodos predeterminados (posibilitados por una línea de base de Java 8) y puede implementarse directamente sin la necesidad de este adaptador
Como se indicó anteriormente, lo que debe hacer es implementar
WebMvcConfigurer
y anular el método
addInterceptors
.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyCustomInterceptor());
}
}