2009-05-22 24 views
6

में HTTPS पर ServletOutputStream का उपयोग करके सर्वलेट से सीएसवी फ़ाइल लौटाना मेरे पास एक सर्वलेट है जो एक सीएसवी फ़ाइल लौटा रहा है जो दोनों इंटरनेट एक्सप्लोरर और फ़ायरफ़ॉक्स में HTTP पर 'काम कर रहा है'। जब मैं HTTPS पर एक ही सर्वलेट निष्पादित करता हूं तो केवल फ़ायरफ़ॉक्स HTTPS पर csv फ़ाइल डाउनलोड करना जारी रखता है। मुझे नहीं लगता कि यह जरूरी एक इंटरनेट 6 या 7 मुद्दा वर्णित on MSDN है:इंटरनेट एक्सप्लोरर

संदेश है:

इंटरनेट एक्सप्लोरर mydomain.com से data.csv डाउनलोड नहीं कर सकते इंटरनेट एक्सप्लोरर में सक्षम नहीं था इसे इंटरनेट साइट खोलें। अनुरोधित साइट या तो अनुपलब्ध है या नहीं मिल सकती है। कृपया बाद में पुनः प्रयास करें।

कृपया ध्यान दें कि साइट अभी भी इस संदेश के बाद 'ऊपर' है और आप साइट ब्राउज़ करना जारी रख सकते हैं, यह केवल सीएसवी का डाउनलोड है जो इस संदेश को संकेत देता है। मैं अन्य j2ee अनुप्रयोगों से IE पर https पर समान फ़ाइलों तक पहुंचने में सक्षम हूं, इसलिए मुझे विश्वास है कि यह हमारा कोड है। क्या हमें bufferedOutputStream बंद नहीं करना चाहिए?

अद्यतन

बंद करने या उत्पादन धारा को बंद करने के लिए नहीं है कि क्या: मैं जावा टुकड़ी मंचों पर इस प्रश्न पूछा और discussion वहाँ भी व्यावहारिक है। अंत में ऐसा लगता है कि इस आउटपुट स्ट्रीम को बंद करने के लिए कोई कंटेनर 'क्लाइंट' (इस मामले में आपका सर्वलेट कोड) पर भरोसा नहीं करना चाहिए। इसलिए यदि आपकी सर्वलेट में स्ट्रीम को बंद करने में आपकी विफलता एक समस्या का कारण बनती है तो यह आपके कोड की तुलना में आपके सर्वलेट कंटेनर के खराब कार्यान्वयन पर अधिक प्रतिबिंब है। मैंने सूर्य, ओरेकल और बीईए से आईडीई और ट्यूटोरियल के व्यवहार को देखा और वे स्ट्रीम को बंद करने या नहीं करने में भी असंगत हैं।

आईई विशिष्ट व्यवहार के बारे में: हमारे मामले में एक अलग उत्पाद 'ओरेकल वेब कैश' अतिरिक्त हैडर मान जो सिर्फ इसलिए जिस तरह के प्रभावों इंटरनेट एक्सप्लोरर आईई 'नहीं कैश' आवश्यकता (see the MSDN article) लागू करता परिचय दे रहा था। कोड है:

public class DownloadServlet extends HttpServlet { 
    public void doGet(HttpServletRequest request, 
         HttpServletResponse response) throws ServletException, 
                  IOException { 
     ServletOutputStream out = null; 
     ByteArrayInputStream byteArrayInputStream = null; 
     BufferedOutputStream bufferedOutputStream = null; 
     try { 
      response.setContentType("text/csv"); 
         String disposition = "attachment; fileName=data.csv"; 
      response.setHeader("Content-Disposition", disposition); 

      out = response.getOutputStream(); 
      byte[] blobData = dao.getCSV(); 

      //setup the input as the blob to write out to the client 
      byteArrayInputStream = new ByteArrayInputStream(blobData); 
      bufferedOutputStream = new BufferedOutputStream(out); 
      int length = blobData.length; 
      response.setContentLength(length); 
      //byte[] buff = new byte[length]; 
      byte[] buff = new byte[(1024 * 1024) * 2]; 

      //now lets shove the data down 
      int bytesRead; 
      // Simple read/write loop. 
      while (-1 != 
        (bytesRead = byteArrayInputStream.read(buff, 0, buff.length))) { 
       bufferedOutputStream.write(buff, 0, bytesRead); 
      } 
      out.flush(); 
      out.close(); 

     } catch (Exception e) { 
      System.err.println(e); throw e; 

     } finally { 
      if (out != null) 
       out.close(); 
      if (byteArrayInputStream != null) { 
       byteArrayInputStream.close(); 
      } 
      if (bufferedOutputStream != null) { 
       bufferedOutputStream.close(); 
      } 
     } 
    } 
+0

फ़ायरफ़ॉक्स काम करता है। क्या आप वर्णन कर सकते हैं कि आईई के साथ क्या होता है? क्या आपको कुछ भी नहीं मिलता है, क्या यह लटकता है, फाइल को छोटा कर दिया जाता है ...? – erickson

+0

एमएसडीएन लेख संदेश को हाइलाइट करता है। मैं जल्द ही संदेश के साथ प्रश्न अद्यतन कर दूंगा। –

उत्तर

4

मैं अपने "सिर में स्तन के माध्यम से पीछे से" लिखने तंत्र के बारे में वास्तव में उलझन में हूँ। क्यों नहीं सरल (सर्वलेट उत्पादन धारा bufferend किया जाएगा, कंटेनर सामान thats):

byte[] csv = dao.getCSV(); 
response.setContentType("text/csv"); 
response.setHeader("Content-Disposition", "attachment; filename=data.csv")); 
reponse.setContentLength(csv.length); 
ServletOutputStream out = response.getOutputStream(); 
out.write(csv); 

वहाँ भी उत्पादन धारा फ्लश करने के लिए और न ही बंद करने के लिए कोई ज़रूरत नहीं होना चाहिए।

हेडर सामग्री को IE द्वारा संवेदनशील केस पार्स नहीं किया जाना चाहिए, लेकिन कौन जानता है: fileName कैमेलकेस न करें। अगला सवाल एन्कोडिंग है। सीएसवी टेक्स्ट है, इसलिए आपको getWriter( का उपयोग करना चाहिए) या जी etOutputStream() और उदाहरण के लिए सामग्री प्रकार "टेक्स्ट/सीएसवी; वर्णसेट = यूटीएफ -8" पर सेट करें। लेकिन dao को सीएसवी को बाइट [] के बजाय स्ट्रिंग के रूप में प्रदान करना चाहिए।

सर्वलेट कोड में HTTPS के साथ कुछ भी नहीं है, इसलिए प्रोटोकॉल सर्वर पक्ष से कोई फर्क नहीं पड़ता। आप उम्मीद के साथ HTTPhost से servlet का परीक्षण कर सकते हैं।

आपके आवेदन में फ़िल्टर के बारे में क्या? एक फिल्टर उदाहरण के लिए कैश-कंट्रोल के साथ एक HTTP शीर्षलेख (या पाद लेख) सेट कर सकता है।

+0

यह एचटीटीपीएस के साथ इंटरनेट एक्सप्लोरर के अपवाद के साथ अधिकांश ब्राउज़रों में HTTP और HTTPS में काम करता है (एमएसडीएन आलेख से जुड़ा एक ही संदेश)। मैं आपके उदाहरण में नोट करता हूं कि आप बाहर नहीं कर रहे हैं। बंद()। मैं पुष्टि की तलाश में हूं कि सर्वलेट को कॉल नहीं करना चाहिए। क्लोज़() भी। –

+0

मैं मानता हूं कि buffered आईओ के साथ सामान अनावश्यक है। ऐसा मत करो। इसी तरह, मुझे नहीं लगता कि स्ट्रीम बंद करना जरूरी है। – jsight

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