2017-11-08 13 views
0

私は、SpringレスポンスアプリケーションでトレースするためにHTTPリクエストとレスポンスボディにアクセスする最適な方法を検討しています。リクエスト/レスポンス本文をSpringのリアクティブ・アプリケーションにコピーしましたか?

以前のバージョンでは、サーブレットフィルタとサーブレットリクエストラッパーを利用して、受信リクエストの入力ストリームを消費し、トレースの非同期処理用のコピーを保持しました(Elasticsearchに送信します)。

しかし、Springのリアクティブなアプリケーション(webfluxを使用)の場合、デコードされる前にリクエストにアクセスするにはどうすればよいでしょうか。何かご意見は?それぞれServerWebExchangeDecoratorServerHttpRequestDecoratorServerHttpResponseDecorator

答えて

0

は、これが提供デコレータを使用して達成することができるが判明しました。ここで

は、リクエストのデフォルトの加入者がその読み取りとしてDataBuffer内容を蓄積サンプル要求デコレータです:

@Slf4j 
class PartnerServerHttpRequestDecorator extends ServerHttpRequestDecorator { 

    private final StringWriter cachedCopy = new StringWriter(); 

    PartnerServerHttpRequestDecorator(ServerHttpRequest delegate) { 
     super(delegate); 
    } 

    @Override 
    public Flux<DataBuffer> getBody() { 
     return super.getBody() 
      .publishOn(single()) 
      .doOnNext(this::cache) 
      .doOnComplete(() -> trace(getDelegate(), cachedCopy.toString())); 
    } 

    private void cache(DataBuffer buffer) { 
     cachedCopy.write(new String(buffer.asByteBuffer().array(), UTF_8)); 
    } 

    private void trace(ServerHttpRequest request, String requestBody) { 
     log.info(requestBody); 
    } 
} 

ちょうどあなたがWebFilterから渡されたServerWebExchangeを飾るとき、あなたはまたにgetRequest()を上書きする、ことを確認してください同様の要求デコレータを返す:フィルター上

public final class PartnerServerWebExchangeDecorator extends ServerWebExchangeDecorator { 

    private final ServerHttpRequestDecorator requestDecorator; 
    private final ServerHttpResponseDecorator responseDecorator; 

    public PartnerServerWebExchangeDecorator(ServerWebExchange delegate) { 
     super(delegate); 
     this.requestDecorator = new PartnerServerHttpRequestDecorator(delegate.getRequest()); 
     this.responseDecorator = new PartnerServerHttpResponseDecorator(delegate.getResponse()); 
    } 

    @Override 
    public ServerHttpRequest getRequest() { 
     return requestDecorator; 
    } 

    @Override 
    public ServerHttpResponse getResponse() { 
     return responseDecorator; 
    } 

} 

を:

そのようなものとして使用することができる
@Component 
public class TracingFilter implements WebFilter { 

    @Override 
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { 
     return chain.filter(new PartnerServerWebExchangeDecorator(exchange)); 
    } 
} 

(静的インポート機能を注意):

@Bean 
public HttpHandler myRoute(MyHandler handler) { 
    final RouterFunction<ServerResponse> routerFunction = 
     route(POST("/myResource"), handler::persistNotification); 
    return webHandler(toWebHandler(routerFunction)) 
     .filter(new TracingFilter()) 
     .build(); 
} 
関連する問題