web-dev-qa-db-fra.com

Spring Boot Ajout d'intercepteurs de requêtes HTTP

Quelle est la bonne façon d'ajouter des intercepteurs HttpRequest dans une application de démarrage de printemps? Ce que je veux faire, c'est enregistrer les demandes et les réponses pour chaque demande http.

La documentation de démarrage de printemps ne couvre pas ce sujet du tout. ( http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/ )

J'ai trouvé des exemples Web expliquant comment faire de même avec les anciennes versions de Spring, mais ceux-ci fonctionnent avec applicationcontext.xml. S'il vous plaît aider.

85
riship89

Puisque vous utilisez Spring Boot, je suppose que vous préférez vous fier à la configuration automatique de Spring dans la mesure du possible. Pour ajouter une configuration personnalisée supplémentaire, comme vos intercepteurs, fournissez simplement une configuration ou un bean de WebMvcConfigurerAdapter.

Voici un exemple de classe de configuration:

@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() {
        ...
    });
  }
}

NOTE ne l'annotez pas avec @EnableWebMvc, si vous souhaitez conserver configuration automatique de Spring Boots pour mvc .

135
ikumen

WebMvcConfigurerAdapter sera déconseillé avec Spring 5. À partir de sa Javadoc :

@deprecated from 5.0 5.0 {@link WebMvcConfigurer} a des méthodes par défaut (rendues possibles par une ligne de base Java 8) et peut être implémenté directement sans que cet adaptateur soit nécessaire.

Comme indiqué ci-dessus, vous devez implémenter WebMvcConfigurer et surcharger la méthode addInterceptors.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyCustomInterceptor());
    }
}
63
sedooe

Pour ajouter un intercepteur à une application de démarrage à ressort, procédez comme suit:

  1. Créer une classe d'intercepteur

    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;
        }
    }
    
  2. Définir une classe de configuration

    @Configuration
    public class MyConfig extends WebMvcConfigurerAdapter{
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("/**");
        }
    }
    
  3. C'est ça. Désormais, toutes vos demandes passeront par la logique définie dans la méthode preHandle () de MyCustomInterceptor.

24
sunitha

J'ai eu le même problème de WebMvcConfigurerAdapter étant déconseillé. Quand j'ai cherché des exemples, je n'ai presque pas trouvé de code implémenté. Voici un morceau de code de travail.

créer une classe qui étend 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;
    }

}

puis implémenter l'interface 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");
    }
}
9
user2532195

Vous pouvez également envisager d'utiliser la bibliothèque open source SpringSandwich, qui vous permet d'annoter directement dans vos contrôleurs Spring Boot les intercepteurs à appliquer, de la même manière que vous annotez vos itinéraires d'URL.

De cette façon, aucune chaîne susceptible de contenir des fautes de frappe - la méthode et les annotations de classe de SpringSandwich survivent facilement au refactoring et expliquent clairement ce qui est appliqué à l'endroit où. (Divulgation: je suis l'auteur).

http://springsandwich.com/

7
Magnus

Étant donné que toutes les réponses à cette requête utilisent l’adaptateur WebMvcConfigurer Adapter abstrait, désormais obsolète depuis longtemps, au lieu de WebMvcInterface (comme déjà noté par @sebdooe), voici un exemple minimal fonctionnel d’une application SpringBoot (2.1.4) avec 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");
    }
}

fonctionne comme annoncé

La sortie vous donnera quelque chose comme:

> 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
6
Xenonite