आप एक फ़िल्टर जोड़ सकते हैं, वर्तमान HttpServletRequest
को रोकें और इसे कस्टम HttpServletRequestWrapper
पर लपेटें। आपके कस्टम HttpServletRequestWrapper
में, आप अनुरोध निकाय को पढ़ते हैं और इसे कैश करते हैं और फिर कैश किए गए मान से पढ़ने के लिए getInputStream
और getReader
लागू करते हैं। अनुरोध लपेटकर के बाद, कैश की गई मूल्य हमेशा मौजूद रहता है के बाद से, आप अनुरोध शरीर को कई बार पढ़ सकते हैं:
@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
MultipleReadHttpRequest wrappedRequest = new MultipleReadHttpRequest(currentRequest);
chain.doFilter(wrappedRequest, servletResponse);
}
}
इस फिल्टर के बाद, हर कोई wrappedRequest
जो पढ़ा जा रहा से अधिक बार की क्षमता है देखेंगे:
public class MultipleReadHttpRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedContent;
public MultipleReadHttpRequest(HttpServletRequest request) throws IOException {
// Read the request body and populate the cachedContent
}
@Override
public ServletInputStream getInputStream() throws IOException {
// Create input stream from cachedContent
// and return it
}
@Override
public BufferedReader getReader() throws IOException {
// Create a reader from cachedContent
// and return it
}
}
MultipleReadHttpRequest
को लागू करने के लिए, आप वसंत ढांचे से ContentCachingRequestWrapper
पर एक नज़र डाल सकते हैं जो मूल रूप से वही काम करता है।
इस दृष्टिकोण के अपने नुकसान हैं। सबसे पहले, यह कुछ हद तक अक्षम है, क्योंकि प्रत्येक अनुरोध के लिए, अनुरोध निकाय कम से कम दो बार पढ़ा जा रहा है। अन्य महत्वपूर्ण दोष यह है कि यदि आपके अनुरोध निकाय में 10 GB
स्ट्रीम की धारा है, तो आप 10 GB
डेटा पढ़ते हैं और इससे भी बदतर आगे की परीक्षा के लिए स्मृति में आते हैं।
स्रोत
2016-01-15 08:23:47
एक समाधान थ्रेडलोकल का उपयोग अनुरोध से फ़िल्टर के अंदर पैरा स्टोर करने के लिए किया जा सकता है और फिर किसी भी समय अपने कोड में कहीं भी उनका उपयोग कर सकता है। –
@ सैंडिपपूनिया इससे मदद मिल सकती है। लेकिन एक समस्या यह है कि, यदि मैं शरीर को थ्रेडलोकल में सहेजता हूं (HttpServletRequest.getReader/getInputStream को कॉल करके), इसे फिर कभी नहीं कहा जाएगा। नियंत्रक परत में घटना, मैं "@RequestBody स्ट्रिंग बॉडी" घोषित नहीं कर सकता (जो वसंत द्वारा अपवाद फेंक सकता है), क्योंकि वसंत अब इनपुट स्ट्रीम नहीं पढ़ सकता है। – Kim