5

मैं एक कोडबेस में स्प्रिंग 5 (5.0.0.आरसी 2) से नया WebClient कोशिश कर रहा हूं जो प्रतिक्रियाशील प्रोग्रामिंग का उपयोग करता है और मैंने अपने ऐप में एक एंडपॉइंट से डीटीओ तक JSON प्रतिक्रिया मैपिंग सफलता प्राप्त की है, जो बहुत काम करता है अच्छा:स्प्रिंग वेब क्लाइंट से क्लाइंट रीस्पॉन्स से बाइट सरणी कैसे प्राप्त करें?

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 के रूप में सेवा) का उपयोग करता है से प्रतिक्रिया शरीर के लिए कोशिश कर रहा हूँ, इसलिए मैं प्रतिक्रिया, से कच्चे बाइट्स प्राप्त करना चाहते हैं जो मैं फिर एक ऑब्जेक्ट को मैप कर दूंगा।

मैं इसे इस गूगल अमरूद से 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() विधि लागू की गई है।

एक StringDecoder जो String को डिकोडिंग का समर्थन करता है नहीं है, जैक्सन से संबंधित डिकोडर का एक समूह (हुड के नीचे अपने डीटीओ उदाहरण में प्रयुक्त), और वहाँ भी एक 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); 
संबंधित मुद्दे