मेरे पास एक सर्वलेट है जो कुछ HTTP अनुरोधों और प्रतिक्रियाओं को संभालता है। मैं ग्राहक को वापस भेजने से पहले प्रतिक्रिया निकाय को लॉग करना चाहता हूं। क्या कोई तरीका है कि मैं प्रतिक्रिया शरीर को HttpServletResponse
ऑब्जेक्ट से सर्वलेट से भेजने से पहले कैप्चर कर सकता हूं?प्रतिक्रिया शरीर को कैप्चर और लॉग करें
उत्तर
यदि मैं आपको सही ढंग से समझता हूं, तो आप प्रतिक्रिया शरीर पर लॉग इन करना चाहते हैं? यह एक बहुत महंगा काम है, लेकिन यदि यह व्यवसाय की आवश्यकता है ...
@duffymo ने बताया, Filter
इसके लिए उपयुक्त स्थान है। आप को HttpServletResponseWrapper
कार्यान्वयन के साथ HttpServletResponse#getWriter()
को अपने कार्यान्वयन के साथ बदलकर प्रतिक्रिया शरीर को कैप्चर कर सकते हैं जो कुछ बफर में प्रतिक्रिया निकाय की प्रतिलिपि बनाता है। प्रतिस्थापित प्रतिक्रिया के साथ फ़िल्टर श्रृंखला जारी रखने के बाद, बस प्रतिलिपि लॉग करें।
यहाँ एक किकऑफ़ उदाहरण है की तरह doFilter()
विधि देख सकते हैं कैसे:
public class CopyPrintWriter extends PrintWriter {
private StringBuilder copy = new StringBuilder();
public CopyPrintWriter(Writer writer) {
super(writer);
}
@Override
public void write(int c) {
copy.append((char) c); // It is actually a char, not an int.
super.write(c);
}
@Override
public void write(char[] chars, int offset, int length) {
copy.append(chars, offset, length);
super.write(chars, offset, length);
}
@Override
public void write(String string, int offset, int length) {
copy.append(string, offset, length);
super.write(string, offset, length);
}
public String getCopy() {
return copy.toString();
}
}
मानचित्र एक url-pattern
पर इस फिल्टर जिसके लिए आप चाहते हैं:
public void doFilter(ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException {
final CopyPrintWriter writer = new CopyPrintWriter(response.getWriter());
chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
@Override public PrintWriter getWriter() {
return writer;
}
});
logger.log(writer.getCopy());
}
यहाँ CopyPrintWriter
की तरह लग रही है कि कैसे कर सकते हैं के लिए प्रतिक्रिया लॉग इन करने के लिए। ध्यान रखें कि छवियों, सीएसएस, जेएस फाइलों जैसी बाइनरी/स्थैतिक सामग्री इस तरह से लॉग इन नहीं की जाएगी। आप उन्हें एक विशिष्ट पर्याप्त url-pattern
का उपयोग कर बहिष्कृत करना चाहते हैं, उदा। प्रश्न में सर्वलेट के *.jsp
या बस servlet-name
पर। यदि आप बाइनरी/स्थैतिक सामग्री को वैसे भी लॉग करना चाहते हैं (जिसके लिए मुझे कोई लाभ नहीं दिखाई देता है), तो आपको HttpServletResponse#getOutputStream()
को उसी तरह से बदलना होगा।
शायद servlet filter आपकी मदद कर सकता है। इसके बारे में HTTP के लिए पहलू उन्मुख प्रोग्रामिंग के रूप में सोचें।
BalusC answer का विकल्प वैकल्पिक रूप से दो आउटपुटस्ट्रीम में लिखने के लिए TeeutputStream का उपयोग करना।
public void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(baos);
chain.doFilter(req,new HttpServletResponseWrapper(res) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps)
);
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(new DelegatingServletOutputStream (new TeeOutputStream(super.getOutputStream(), ps))
);
}
});
//Get Response body calling baos.toString();
}
भविष्य की पीढ़ियों के लाभ के लिए ... कौन सी लाइब्रेरी 'टीओयूटपुटस्ट्रीम' और 'डिलीगेटिंग सर्लेटऑटपुटस्ट्रीम' हैं? –
यह वसंत और अपाचे io से है। 1) https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/mock/web/DelegatingServletOutputStream.html 2) https://commons.apache.org/proper/commons-io /javadocs/api-1.4/org/apache/commons/io/output/TeeOutputStream.html – Happier
मैं तृतीय पक्ष निर्भरता के बिना आउटपुटस्ट्रीम संस्करण बना देता हूं, जो @pdorgambide के समान है। आप this link में पा सकते हैं।
- 1. कैप्चर आउटपुट को कैप्चर और लॉग कैसे करें?
- 2. लॉग जैक्स-डब्ल्यूएस http अनुरोध और प्रतिक्रिया
- 3. SoapHttpClientProtocol लॉग प्रतिक्रिया xml
- 4. HTTP 500 शरीर के साथ प्रतिक्रिया?
- 5. प्रतिक्रिया सामग्री शरीर मुद्रण जब डेटा
- 6. प्रतिक्रिया प्रतिक्रिया होने पर संपूर्ण प्रतिक्रिया निकाय प्राप्त करें?
- 7. एंड्रॉइड स्क्रीन कैप्चर करें और प्रोग्राम को
- 8. टॉमकैट स्टार्टअप लॉग कैप्चर करने के लिए कैसे करें
- 9. सीकबार मूल्यों को कैप्चर करें
- 10. जेएमटर - असफल प्रतिक्रिया के लिए पूर्ण अनुरोध कैसे लॉग करें?
- 11. डीएनएस रिसाव कैप्चर करें
- 12. रैक प्रतिक्रिया शरीर एक सरणी क्यों नहीं है?
- 13. HTTP शीर्षलेख या प्रतिक्रिया शरीर में शेष त्रुटि संदेश?
- 14. पृष्ठ पर शरीर को कैसे केंद्रित करें?
- 15. मोनोटouch कैमरा छवि कैप्चर और अपलोड करें
- 16. उपयोगकर्ता इनपुट कैप्चर करें और बटन
- 17. वेबपृष्ठ के स्क्रीनशॉट को कैप्चर करें और छवि (एएसपी.नेट)
- 18. एसक्लएक्सप्शन कैप्चर और हैंडलिंग
- 19. एंड्रॉइड - फोटो कैप्चर करें
- 20. एसएलईएमई में किसी एजेंट के स्टडआउट/लॉग आउटपुट को कैप्चर कैसे करें?
- 21. जेएसपी आउटपुट कैप्चर करें,
- 22. कैप्चर करें IFrame
- 23. चेतावनी प्रतिक्रिया शरीर की सामग्री-लंबाई निर्धारित नहीं कर सका। सेट प्रतिक्रिया की या सामग्री-लंबाई सेट प्रतिसाद # chunked = सच
- 24. एंट आउटपुट कैप्चर करें
- 25. सभी विंडोज संदेशों को कैप्चर करें
- 26. कॉल स्टैक को तुरंत कैप्चर करें
- 27. स्क्रॉलिंग विंडो सामग्री को कैप्चर करें स्क्रीनशॉट
- 28. स्क्रीनशॉट कैप्चर करें .NET
- 29. एक्सएसएल कैप्चर करें: जावा
- 30. सामने वाले कैमरे को कैप्चर करें - फोनगैप?
की प्रतिलिपि बनाने के संकेत को याद करता है आपको केवल ओवरराइड नहीं करना चाहिए 'getWriter()', लेकिन 'getOutputStream() ' – pihentagy
समस्याओं को एन्कोड करने के बारे में कैसे? – pihentagy
@pihentagy: 1) यदि आपको आवश्यकता है। 2) 'setCharacterEncoding()' विधि द्वारा सेट किया गया वही उपयोग करें। – BalusC