5

私は、リアクティブプログラミングを使用するコードベースでSpring5(5.0.0.RC2)から新しいWebClientを試しています。私はJSONレスポンスをエンドポイントからアプリケーションのDTOにマッピングすることに成功しました。素敵:Spring WebClientのClientResponseからバイト配列を取得するにはどうすればよいですか?

WebClient client = WebClient.create(baseURI); 
Mono<DTO> dto = client.get() 
     .uri(uri) 
     .accept(MediaType.APPLICATION_JSON) 
     .exchange() 
     .flatMap(response -> response.bodyToMono(DTO.class)); 

は、しかし、今私は(バイナリデータがapplication/octet-streamを務めた)プロトコルバッファを使用するエンドポイントからのレスポンスボディにしようとしているので、私は応答から生のバイトを取得したいのですが、どの次にオブジェクトにマップします。

私はそれがGoogleのグアバからBytesを使用して、このように動作するようになった:

Mono<byte[]> bytes = client.get() 
     .uri(uri) 
     .accept(MediaType.APPLICATION_OCTET_STREAM) 
     .exchange() 
     .flatMapMany(response -> response.body(BodyExtractors.toDataBuffers())) 
     .map(dataBuffer -> { 
      ByteBuffer byteBuffer = dataBuffer.asByteBuffer(); 
      byte[] byteArray = new byte[byteBuffer.remaining()]; 
      byteBuffer.get(byteArray, 0, bytes.length); 
      return byteArray; 
     }) 
     .reduce(Bytes::concat) 

これは動作しますが、これらのバイトを取得するために簡単に、よりエレガントな方法は何ですか?

答えて

8

ClientResponse.bodyToMono()は、最後に指定されたクラスをサポートすると主張するいくつかのorg.springframework.core.codec.Decoderを使用します。

Decoderのクラス階層、特にdecodeToMono()メソッドがどのように実装されているかを確認する必要があります。

StringにデコードをサポートしていStringDecoder、(フードの下、あなたのDTOの例で使用)・ジャクソン関連のデコーダの束があり、そして特に重要であるResourceDecoderもあります。

ResourceDecoderorg.springframework.core.io.InputStreamResourceおよびorg.springframework.core.io.ByteArrayResourceをサポートします。 ByteArrayResourceは本質的にはbyte[]のラッパーであるため、次のコードは、応答本体へのアクセスをバイト配列として提供します。

Mono<byte[]> mono = client.get() 
      ... 
      .exchange() 
      .flatMap(response -> response.bodyToMono(ByteArrayResource.class)) 
      .map(ByteArrayResource::getByteArray); 
関連する問題