बी

2015-12-07 20 views
14

में पूरी फ़ाइल भंडारण के बिना सिस्टम A-> बी> सेल्सियस के बीच फ़ाइल भेजा जा रहा है मैं 3 अलग वसंत वेब अनुप्रयोगोंबी

है
  • एक का उपयोग करता है वसंत 4.x
  • बी वसंत 3.2 का उपयोग करता है .0
  • सी वसंत 4.x का उपयोग करता

बी और सी फ़ाइलों को अपलोड करने के लिए

बाकी नियंत्रकों को उजागर करता है
  • एक पढ़ता
  • बी फ़ाइल सामग्री
  • पढ़ने के लिए किसी भी आवश्यकता के बिना सी लिए अनुरोध भेजता है यह बी करने के लिए फ़ाइल और अपलोड
  • और फिर सी जो भी वह फ़ाइल के साथ चाहता है करता है।

तो प्रवाह होगा A-> बी> सी

मेरा प्रश्न है - इस तरह से सेटअप बी लिए यह संभव है ताकि बी पूरी की दुकान नहीं होगा मेमोरी में फ़ाइल करें, लेकिन इनकमिंग स्ट्रीम पढ़ेगी और इसे सी पर अग्रेषित करेगी?

मैं क्या करने में कामयाब रहे है: एक

public void sendFileFromA() throws FileNotFoundException { 
    final InputStream fis = new FileInputStream(new File("someFile")); 
    final RequestCallback requestCallback = new RequestCallback() { 
     @Override 
     public void doWithRequest(final ClientHttpRequest request) throws IOException { 
      request.getHeaders().add("Content-type", "application/octet-stream"); 
      IOUtils.copy(fis, request.getBody()); 
     } 
    }; 
    final RestTemplate restTemplate = new RestTemplate(); 
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 
    requestFactory.setBufferRequestBody(false); 
    restTemplate.setRequestFactory(requestFactory); 

    final HttpMessageConverterExtractor<String> responseExtractor = new HttpMessageConverterExtractor<>(
      String.class, restTemplate.getMessageConverters()); 
    restTemplate.execute("http://b_url/upload", HttpMethod.POST, requestCallback, responseExtractor); 
} 

बी

@RequestMapping(value = "/upload", method = RequestMethod.POST) 
public @ResponseBody String handleFileUpload(HttpServletRequest request) throws IOException { 
    final ServletInputStream input = request.getInputStream(); 

    final RequestCallback requestCallback = new RequestCallback() { 
     @Override 
     public void doWithRequest(final ClientHttpRequest request) throws IOException { 
      request.getHeaders().add("Content-type", "application/octet-stream"); 
      try (OutputStream body = request.getBody()) { 
       IOUtils.copy(input, body); 
      } 
     } 
    }; 
    final RestTemplate restTemplate = new RestTemplate(); 
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 
    requestFactory.setBufferRequestBody(false); 
    restTemplate.setRequestFactory(requestFactory); 

    final HttpMessageConverterExtractor<String> responseExtractor = new HttpMessageConverterExtractor<>(
      String.class, restTemplate.getMessageConverters()); 
    restTemplate.execute("http://c_url/upload", HttpMethod.POST, requestCallback, responseExtractor); 

    return "success"; 
} 

सी

@RequestMapping(value = "/upload", method = RequestMethod.POST) 
public @ResponseBody String handleFileUpload(HttpServletRequest request) throws IOException { 
    ServletInputStream input = request.getInputStream(); 

    try (BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream("zibiTest"))) { 
     IOUtils.copy(input, output); 
    } 
    return "success"; 
} 

मैं बी

का उपयोग करके फ़ाइलों को आसानी से प्रतिलिपि बना सकता है। ऐसे समाधान के साथ हम ए को रोकने के दौरान ए को रोकने की कोशिश कर सकते हैं, बी और सी को त्रुटि के बारे में अधिसूचित किया जाना चाहिए, लेकिन कभी-कभी ऐसा होता है कि त्रुटि संदेश सी तक नहीं पहुंचता है - यह सॉकेट टाइमआउट अपवाद के साथ बंद हो जाता है, कोई विचार क्यों होता है और इसे ठीक से कैसे कार्यान्वित किया जाए?

क्या यह एक वैध दृष्टिकोण है या इसे बेहतर तरीके से संभाला जा सकता है?

+1

आदेश में एक फ़ाइल आप लोड करने के लिए की जरूरत है पढ़ने के लिए "मेरी जानकारी समस्या यह है कि केवल आप को देखने के लिए सीमित है, तो मैं एकमात्र समाधान के लिए एक मध्यम और समाधान ही नहीं हो सकता है" स्मृति के लिए बी में फ़ाइल प्राप्त करने वाली व्हील फ़ाइल पहले से ही स्मृति में है। – reos

+0

फ़ाइल को बी में एक थ्रेड में एक पाइप में लिखें, फिर उसे सी में भेजने से पहले इसे (बी में भी) में पढ़ें। Java.nio.channels.Pipe देखें। सी यह जानना चाहता है कि यह कितना डेटा प्राप्त करने वाला है (http शीर्षलेख)। –

+1

@reos अच्छी तरह से, कोई फ़ाइल का हिस्सा पढ़ सकता है, इसके साथ कुछ कर सकता है, फिर अगला भाग पढ़ें, ... – Henry

उत्तर

6

मैं बी पर आपके पास छोटे सॉकेट टाइमआउट को सेट करने की कोशिश करता हूं। वर्तमान में ऐसा लगता है कि दोनों के पास कुछ डिफ़ॉल्ट मान है, इसलिए अगर ए लटकता है, तो बी और सी दोनों डेटा लगभग एक ही समय में बंद हो जाएंगे। दोनों समय समाप्त हो जाते हैं, और शायद यह दौड़ की स्थिति है, जहां यह टाइमआउट सटीकता पर निर्भर करता है जो पहले एक बार बाहर होता है।

+1

पहले (दो) उपधारा पर आपका क्या लेना है? मेरे लिए ऐसा लगता है कि बी पारगमन के दौरान पूरी फ़ाइल को स्टोर नहीं करता है, उसके बाद उसे बी नियंत्रक में 'ServletInputStream' मिला है और उदाहरण के लिए बाइट सरणी नहीं है। –

0

क्या आपने फ्ल्यूम के बारे में सोचा है? जो मैं देख सकता हूं, उससे चुनौती बी में स्टोर नहीं करना है और फाइलें मुझे लगता है कि वे बड़े हो सकते हैं।ऐसे मामलों में क्यों सीधे चैनल पर फ़ाइलों को स्ट्रीम करने के अपाचे फ्लम तरीके का उपयोग न करें और फिर अपने सिंक पर जो आपका बी होगा और इसे आपके अंतिम गंतव्य "सी" पर डंप करेगा। हालांकि फ़ाइल बड़ी है, यह कमान मदद करता है।

किसी के रूप में कहा गया है,

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