2016-04-02 8 views
11

के साथ इनपुटस्ट्रीम प्राप्त करना मैं इसमें से इनपुटस्ट्रीम पढ़ने के लिए यूआरएल क्लास का उपयोग कर रहा हूं। क्या कोई तरीका है कि मैं इसके लिए RestTemplate का उपयोग कर सकता हूं?RestTemplate

InputStream input = new URL(url).openStream(); 
JsonReader reader = new JsonReader(new InputStreamReader(input, StandardCharsets.UTF_8.displayName())); 

मैं कैसे RestTemplate बजाय URL उपयोग करने के साथ InputStream मिल सकता है?

उत्तर

2

आपको नहीं करना चाहिए। RestTemplate प्रतिक्रिया (और अनुरोध) सामग्री को संसाधित करने के लिए है।

इसके बजाय, आप उपयुक्त HttpMessageConverter ऑब्जेक्ट्स पंजीकृत कर सकते हैं। HttpInputMessage ऑब्जेक्ट के माध्यम से, प्रतिक्रिया के InputStream तक पहुंच होगी।

As Abdull suggests, स्प्रिंग Resource के लिए एक HttpMessageConverter कार्यान्वयन जो अपने आप में एक InputStream, ResourceHttpMessageConverter लपेटता के साथ आता है। यह सभी Resource प्रकारों का समर्थन नहीं करता है, लेकिन चूंकि आपको किसी भी तरह इंटरफेस के लिए प्रोग्रामिंग होना चाहिए, आपको केवल सुपरइंटरफेस Resource का उपयोग करना चाहिए।

वर्तमान कार्यान्वयन (4.3.5), को ByteArrayInputStream पर कॉपी की गई प्रतिक्रिया स्ट्रीम की सामग्री के साथ लौटाएगा, जिसे आप एक्सेस कर सकते हैं।

आपको स्ट्रीम को बंद करने की आवश्यकता नहीं है। RestTemplate आपके लिए इसका ख्याल रखता है। (यह दुर्भाग्य की बात है कि यदि आप एक InputStreamResource, एक अन्य प्रकार ResourceHttpMessageConverter द्वारा समर्थित उपयोग करने का प्रयास है, क्योंकि यह अंतर्निहित प्रतिक्रिया के InputStream लपेटता लेकिन इससे पहले कि यह अपने ग्राहक कोड से अवगत कराया जा सकता है बंद कर दिया है।)

1

एक संस्करण आप उपभोग कर सकते हैं के रूप में बाइट के रूप में और धर्मांतरित से प्रतिक्रिया स्ट्रीम करने के लिए

byte data[] = restTemplate.execute(link, HttpMethod.GET, null, new BinaryFileExtractor()); 
return new ByteArrayInputStream(data); 

एक्सट्रैक्टर

public class BinaryFileExtractor implements ResponseExtractor<byte[]> { 

    @Override 
    public byte[] extractData(ClientHttpResponse response) throws IOException { 
    return ByteStreams.toByteArray(response.getBody()); 
    } 
} 
12

स्प्रिंग एक org.springframework.http.converter.ResourceHttpMessageConverter है। यह वसंत के org.springframework.core.io.Resource वर्ग को परिवर्तित करता है। कि Resource कक्षा InputStream को घेरती है, जिसे आप someResource.getInputStream() के माध्यम से प्राप्त कर सकते हैं।

इस लाना सब एक साथ, आप वास्तव में एक InputStreamRestTemplate के माध्यम से बाहर के बॉक्स अपने RestTemplate मंगलाचरण की प्रतिक्रिया प्रकार के रूप में Resource.class निर्दिष्ट करने के द्वारा प्राप्त कर सकते हैं।

यहाँ एक उदाहरण RestTemplate के exchange(..) तरीकों में से एक का उपयोग कर रहा है:

import org.springframework.web.client.RestTemplate; 
import org.springframework.http.HttpMethod; 
import org.springframework.core.io.Resource; 

ResponseEntity<Resource> responseEntity = restTemplate.exchange(someUrlString, HttpMethod.GET, someHttpEntity, Resource.class); 

InputStream responseInputStream; 
try { 
    responseInputStream = responseEntity.getBody().getInputStream(); 
} 
catch (IOException e) { 
    throw new RuntimeException(e); 
} 

// use responseInputStream 
+0

'responseEntity.getBody()। GetInputStream(); 'गलत है। कोई getInputStream विधि नहीं है। –

+0

@ ब्रेनस्टॉर्म, पुराने संस्करण और वसंत-कोर-3.1.1.RELEASE' से नए संस्करणों में एक ['org.springframework.core.io.Resource'] है (https://docs.spring.io/spring/docs/ वर्तमान/javadoc-api/org/springframework/core/io/Resource.html) जो 'org.springframework.core.io.InputStreamSource' को बढ़ाता है जो' getInputStream() ' – Abdull

6

पिछले जवाब गलत नहीं हैं, लेकिन वे गहराई है कि मैं देखना पसंद में नहीं जाते। ऐसे मामले हैं जब निम्न स्तर InputStream से निपटने के लिए केवल वांछनीय नहीं है, लेकिन आवश्यक है, सबसे आम उदाहरण स्रोत (कुछ वेब सर्वर) से गंतव्य (डेटाबेस) तक एक बड़ी फ़ाइल स्ट्रीम कर रहा है। यदि आप ByteArrayInputStream का उपयोग करने का प्रयास करते हैं, तो आप आश्चर्यजनक रूप से नहीं होंगे, OutOfMemoryError के साथ बधाई दी। हां, आप अपना खुद का HTTP क्लाइंट कोड रोल कर सकते हैं, लेकिन आपको ग़लत प्रतिक्रिया कोड, प्रतिक्रिया कन्वर्टर्स इत्यादि से निपटना होगा। यदि आप पहले ही स्प्रिंग का उपयोग कर रहे हैं, तो RestTemplate एक प्राकृतिक विकल्प है।

इस लेखन के रूप में, spring-web:5.0.2.RELEASE एक ResourceHttpMessageConverter एक boolean supportsReadStreaming है, जो अगर सेट है कि है, और प्रतिक्रिया प्रकार InputStreamResource है, रिटर्न InputStreamResource; अन्यथा यह ByteArrayResource देता है। तो स्पष्ट रूप से, आप एकमात्र ऐसा नहीं हैं जो समर्थन स्ट्रीमिंग के लिए कहा जाता है।

हालांकि, एक समस्या है: RestTemplateHttpMessageConverter रनों के तुरंत बाद प्रतिक्रिया को बंद कर देता है। इस प्रकार, भले ही आपने InputStreamResource के लिए पूछा, और इसे प्राप्त किया, यह अच्छा नहीं है, क्योंकि प्रतिक्रिया स्ट्रीम बंद कर दी गई है। मुझे लगता है कि यह एक डिजाइन दोष है जिसे उन्होंने अनदेखा किया; यह प्रतिक्रिया प्रकार पर निर्भर होना चाहिए था। तो दुर्भाग्यवश, पढ़ने के लिए, आपको पूरी तरह से प्रतिक्रिया का उपभोग करना होगा; RestTemplate का उपयोग करते समय आप इसे पास नहीं कर सकते हैं।

लेखन हालांकि कोई समस्या नहीं है। यदि आप InputStream स्ट्रीम करना चाहते हैं, तो ResourceHttpMessageConverter आपके लिए यह करेगा। हुड के तहत, से OutputStream पर 4096 बाइट लिखने के लिए org.springframework.util.StreamUtils का उपयोग करता है।

HttpMessageConverter कुछ मीडिया प्रकारों का समर्थन करते हैं, इसलिए आपकी आवश्यकता के आधार पर, आपको डिफ़ॉल्ट लोगों को RestTemplate से हटा देना पड़ सकता है, और जिन्हें आप चाहते हैं उन्हें सेट करें, उनके रिश्तेदार आदेश के प्रति सावधान रहें।

इतना ही नहीं बल्कि, ClientHttpRequestFactory के कार्यान्वयन एक boolean bufferRequestBody है कि आप कर सकते हैं, और चाहिए, false करने के लिए सेट करता है, तो आप एक बड़ी धारा अपलोड कर रहे हैं। अन्यथा, आप जानते हैं, OutOfMemoryError। इस लेखन के अनुसार, SimpleClientHttpRequestFactory (जेडीके क्लाइंट) और HttpComponentsClientHttpRequestFactory (अपाचे HTTP क्लाइंट) इस सुविधा का समर्थन करते हैं, लेकिन OkHttp3ClientHttpRequestFactory नहीं। फिर, डिजाइन निरीक्षण।

संबंधित मुद्दे