web-dev-qa-db-ja.com

Httpリクエストインターセプターを追加するSpring Boot

スプリングブートアプリケーションにHttpRequestインターセプターを追加する正しい方法は何ですか?私がやりたいことはすべてのhttpリクエストのリクエストとレスポンスをログに記録することです。

Spring bootドキュメンテーションはこのトピックを全くカバーしていません。 ( http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

以前のバージョンのspringで同じことをする方法についてのWebサンプルをいくつか見つけましたが、それらはapplicationcontext.xmlで動作します。助けてください。

80
riship89

Spring Bootを使っているので、できる限りSpringの自動設定に頼りたいと思います。インターセプターのような追加のカスタム設定を追加するには、単にWebMvcConfigurerAdapterの設定またはbeanを提供してください。

これが設定クラスの例です。

@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保持したい場合は、これに@EnableWebMvcを付けないでください Spring Bootsのmvcの自動設定

128
ikumen

WebMvcConfigurerAdapterはSpring 5で廃止予定になります。 Javadoc から:

@ 5.0では廃止予定{@link WebMvcConfigurer}にはデフォルトのメソッドがあり(Java 8ベースラインによって可能になりました)、このアダプタを必要とせずに直接実装することができます。

上記のように、あなたがすべきことはWebMvcConfigurerを実装し、addInterceptorsメソッドをオーバーライドすることです。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

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

スプリングブートアプリケーションにインターセプターを追加するには、次の手順に従います。

  1. インターセプタークラスを作成する

    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. 構成クラスを定義する

    @Configuration
    public class MyConfig extends WebMvcConfigurerAdapter{
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("/**");
        }
    }
    
  3. それでおしまい。これで、すべてのリクエストはMyCustomInterceptorのpreHandle()メソッドで定義されたロジックを通過します。

23
sunitha

私はWebMvcConfigurerAdapterが廃止されるのと同じ問題を抱えていました。例を検索したところ、実装されたコードはほとんど見つかりませんでした。これが実用的なコードです。

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;
    }

}

それから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

また、あなたのURLルートに注釈を付けるのと同じように、適用するインターセプタにSpring Bootコントローラに直接注釈を付けることができるオープンソースのSpringSandwichライブラリを使用することを検討するかもしれません。

そのようにして、入力ミスが発生しやすい文字列 - SpringSandwichのメソッドとクラスのアノテーションはリファクタリングを簡単に乗り越えて、どこに適用されているのかを明確にします。 (開示:私は作者です)。

http://springsandwich.com/

7
Magnus

これに対するすべての応答は、WebMvcInterfaceの代わりに現在は非推奨になっている抽象WebMvcConfigurerアダプタを使用しているので(@sebdooeで既に説明したように)、これはインターセプタを備えたSpringBoot(2.1.4)アプリケーションの最低限の例です。

最小限。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");
    }
}

広告通りに動作

出力は以下のようになります。

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