2012-03-11 8 views
5

को मैं FreemarkerView प्रतिपादन का परिणाम पढ़ने के लिए कोशिश कर रहा हूँ:पढ़ना ServletOutputStream स्ट्रिंग

View view = viewResolver.resolveViewName(viewName, locale); 
view.render(model, request, mockResponse); 

परिणाम पढ़ने के लिए, मैं mockResponse बनाया है, जो HttpServletResponse समाहित:

public class HttpServletResponseEx extends HttpServletResponseWrapper { 

    ServletOutputStream outputStream; 

    public HttpServletResponseEx(HttpServletResponse response) throws IOException { 
     super(response); 
     outputStream = new ServletOutputStreamEx(); 
    } 

    @Override 
    public ServletOutputStream getOutputStream() { 
     return outputStream; 
    } 

    @Override 
    public PrintWriter getWriter() throws IOException { 
     return new PrintWriter(new OutputStreamWriter(outputStream, "UTF-8")); 
    } 
} 

और यह भी मेरी ServletOutputStream, जो स्ट्रिंगबिल्डर का उपयोग कर स्ट्रिंग बनाता है:

public class ServletOutputStreamEx extends ServletOutputStream { 

    StringBuilder stringBuilder; 

    public ServletOutputStreamEx() { 
     this.stringBuilder = new StringBuilder(); 
    } 

    @Override 
    public void write(int b) throws IOException { 
    } 

    @Override 
    public void write(byte b[], int off, int len) throws IOException { 
     stringBuilder.append(new String(b, "UTF-8")); 
    } 

    @Override 
    public String toString() { 
     return stringBuilder.toString(); 
    } 
} 

उन लोगों के साथ मैं विधि ServletOutputStreamEx.toString के साथ आसानी से प्रतिक्रिया को पढ़ने में सक्षम हूं।

मेरी समस्या यह है कि लेखन विधि को सही क्रम में नहीं कहा जाता है और अंत में अंतिम स्ट्रिंग मिश्रित है और सही क्रम में नहीं है। यह शायद फ्रीमार्कर में समेकन के कारण होता है, लेकिन मुझे नहीं पता कि इसे कैसे ठीक किया जाए।

+1

मुझे यकीन है कि रेंडरिंग चरण के दौरान फ्रीमार्कर द्वारा सही क्रम में लेखन विधियों को बुलाया जाता है, अन्यथा यह एक गैबल परिणाम उत्पन्न करेगा। इसके अलावा, फ्रीमार्कर को समवर्ती रूप से निष्पादित नहीं किया जाता है। मुझे लगता है कि समस्या 'ServletOutputStreamEx' के आपके कार्यान्वयन में है। आपने सभी लेखन विधियों और इसके सुपर के तरीकों को ओवरराइड नहीं किया है। मुझे नहीं लगता कि आप 'super.write (int b)' कहें, अगर यह विधि कहा जाता है तो यह कुछ भी नहीं करेगा। – gigadot

+1

मुझे यकीन नहीं है कि आपकी समस्या क्या है, लेकिन यदि आपको दो 'स्ट्रिंग' की तरह मिलती है, तो 'ServletOutputStreamEx.write()' कॉल एक साथ मिश्रित होते हैं। 'स्ट्रिंगबिल्डर' के बजाय 'स्ट्रिंगबफर' का उपयोग करके यह ठीक हो जाएगा- 'स्ट्रिंगबफर' सिंक्रनाइज़ किया गया है- –

+1

मैं सहमत नहीं हो सकता, स्ट्रिंगबफर कुछ ऐसा है जिसे बहिष्कृत किया जाना चाहिए (जैसा कि प्रभावी जावा, द्वितीय संस्करण में वर्णित है), और स्ट्रिंगबिल्डर का उपयोग करना है अच्छा, क्योंकि ज्यादातर समय एक ही अनुरोध (और इसलिए एक प्रतिक्रिया) थ्रेड के साथ संभाला जाता है। –

उत्तर

4

प्रतिक्रियाओं के लिए धन्यवाद: write(int b) लागू नहीं किया गया था, क्योंकि इसे कभी नहीं कहा जाता है। अंत में समस्या बाइट सरणी है, जिसमें पिछले स्ट्रिंग भी शामिल है। इसलिए स्ट्रिंग को String(b, off, len, "UTF-8") के रूप में बनाया जाना चाहिए।

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