私は、Spring 5(5.0.0.RC2)の新しいWebClient
をリアクティブプログラミングを使用するコードベースで試してみましたが、エンドポイントからのJSON応答をアプリのDTOにマッピングすることに成功しました。それはとてもうまくいきます:
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 Guavaの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)
これは機能しますが、これらのバイトを取得するより簡単でエレガントな方法はありますか?
最後にClientResponse.bodyToMono()
は、指定されたクラスをサポートすると主張する_org.springframework.core.codec.Decoder
_をいくつか使用します。
したがって、Decoder
のクラス階層、特にdecodeToMono()
メソッドが実装されている場所と方法を確認する必要があります。
StringDecoder
へのデコードをサポートするString
があります。これは、Jackson関連のデコーダーの束(DTOの例で内部的に使用されています)であり、ResourceDecoder
もあります。特に興味深い。
ResourceDecoder
は_org.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);
_