दिलचस्प पोस्ट
जीएमएम एसएमटीपी सर्वर से कनेक्ट होने के लिए जवामेल का उपयोग पोर्ट निर्दिष्ट करता है और 25 का इस्तेमाल करने की कोशिश करता है Ctypes के लिए रनटाइम पर LD_LIBRARY_PATH बदलना PHP – स्ट्रिंग में वैरिएबल सम्मिलित या सीधे सम्मिलित करें विशिष्ट स्थिति में तत्वों को तत्वों में कैसे डालें? पायथन कोड फ़ंक्शन में तेजी से क्यों चलता है? Google के साथ लॉगिन करने के लिए जहां मैं एक अनुप्रयोग का लॉगआउट कैसे करें IAuth2 का उपयोग कैसे करें? फ़ोन नंबर को तेजी से कॉल करना पंक्तियों को स्वाइप करते हुए या संपादित करें बटन पर क्लिक करते समय UITableViewCell में डिफ़ॉल्ट लाल रंग हटाएं बटन का रंग बदलें HttpServletRequest यूआरएल को पूरा करने के लिए JAXB का उपयोग करके सीडीएटीए ब्लॉक कैसे उत्पन्न किया जाता है? एक क्वेरी की कुंजी में MongoDB वाइल्डकार्ड डाउनलोड का समय शेष (सही) का अनुमान कैसे करें? मैं बाश में कमांड लाइन तर्क कैसे पार्स कर सकता हूँ? मैं आरक्षित शब्दों से किस प्रकार से बचता हूं जो स्तंभ नामों के रूप में इस्तेमाल होता है? MySQL / तालिका बनाएं उदाहरण के साथ जावास्क्रिप्ट मॉड्यूल पैटर्न

Request.getInputStream () कई बार कैसे पढ़ें

मेरे पास यह कोड है:

@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("Filter start..."); HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String ba = getBaId(getBody(httpRequest)); if (ba == null) { logger.error("Wrong XML"); httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); } else { if (!clients.containsKey(ba)) { clients.put(ba, 1); logger.info("Client map : init..."); } else { clients.put(ba, clients.get(ba).intValue() + 1); logger.info("Threads for " + ba + " = " + clients.get(ba).toString()); } chain.doFilter(request, response); } } 

और यह web.xml (संकुल छोटा और नाम बदल गए हैं, लेकिन यह वही दिखता है)

 <?xml version="1.0" encoding="ISO-8859-1"?> <web-app> <filter> <filter-name>TestFilter</filter-name> <filter-class>pkg.TestFilter</filter-class> </filter> <filter-mapping> <filter-name>TestFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>Name</servlet-name> <display-name>Name</display-name> <servlet-class>pkg.Name</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Name</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app> 

फ़िल्टर के बाद मैं सर्विसलेट को लागू करना चाहता हूं। मैं chain.doFilter(...) उम्मीद कर रहा था। chain.doFilter(...) चाल कर सकता था, लेकिन मुझे हमेशा यह त्रुटि श्रृंखला के साथ लाइन पर chain.doFilter(...) :

 java.lang.IllegalStateException: getInputStream() can't be called after getReader() at com.caucho.server.connection.AbstractHttpRequest.getInputStream(AbstractHttpRequest.java:1933) at org.apache.cxf.transport.http.AbstractHTTPDestination.setupMessage(AbstractHTTPDestination.java:249) at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:82) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:283) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:166) at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:174) at org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServlet.java:152) at javax.servlet.http.HttpServlet.service(HttpServlet.java:153) at javax.servlet.http.HttpServlet.service(HttpServlet.java:91) at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:103) at pkg.TestFilter.doFilter(TestFilter.java:102) at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:87) at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:187) at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:265) at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:273) at com.caucho.server.port.TcpConnection.run(TcpConnection.java:682) at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743) at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662) at java.lang.Thread.run(Thread.java:619) 

वेब के समाधान से एकत्रित समाधान "Request.getInputStream () कई बार कैसे पढ़ें"

हो सकता है कि आप संभवतः getReader() का उपयोग करते हुए getReader() का उपयोग करते हैं:

 String ba = getBaId(getBody(httpRequest)); 

आपका getInputStream() उसी अनुरोध पर getInputStream() को कॉल करने की कोशिश करता है, जिसे अनुमति नहीं है। आपको क्या करने की ज़रूरत है अनुरोध के शरीर की प्रतिलिपि बनाने के लिए एक ServletRequestWrapper का उपयोग करें, ताकि आप इसे कई तरीकों से पढ़ सकें। मुझे एक पूर्ण उदाहरण जानने का समय नहीं है … माफ करना …

स्वीकृत उत्तर के आधार पर वर्किंग कोड।

 public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper { private static final Logger logger = Logger.getLogger(CustomHttpServletRequestWrapper.class); private final String body; public CustomHttpServletRequestWrapper(HttpServletRequest request) { super(request); StringBuilder stringBuilder = new StringBuilder(); BufferedReader bufferedReader = null; try { InputStream inputStream = request.getInputStream(); if (inputStream != null) { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); char[] charBuffer = new char[128]; int bytesRead = -1; while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { stringBuilder.append(charBuffer, 0, bytesRead); } } else { stringBuilder.append(""); } } catch (IOException ex) { logger.error("Error reading the request body..."); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException ex) { logger.error("Error closing bufferedReader..."); } } } body = stringBuilder.toString(); } @Override public ServletInputStream getInputStream () throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); ServletInputStream inputStream = new ServletInputStream() { public int read () throws IOException { return byteArrayInputStream.read(); } }; return inputStream; } } 

सर्विलेट अनुरोध में इनस्टस्ट्रीम केवल एक बार इस्तेमाल किया जा सकता है क्योंकि यह स्ट्रीम है, आप इसे स्टोर कर सकते हैं और फिर उसे एक बाइट सरणी से प्राप्त कर सकते हैं, यह हल कर सकता है।

 public class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper { private final byte[] body; public HttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); body = StreamUtil.readBytes(request.getReader(), "UTF-8"); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return byteArrayInputStream.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener arg0) { } }; } 

}

फ़िल्टर में:

 ServletRequest requestWrapper = new HttpServletRequestWrapper(request); 

यह मेरे लिए काम किया यह getInputStream लागू getInputStream

 private class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private byte[] body; public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); try { body = IOUtils.toByteArray(request.getInputStream()); } catch (IOException ex) { body = new byte[0]; } } @Override public ServletInputStream getInputStream() throws IOException { return new ServletInputStream() { ByteArrayInputStream bais = new ByteArrayInputStream(body); @Override public int read() throws IOException { return bais.read(); } }; } } 

तब आप अपनी विधि में उपयोग करते हैं:

 //copy body servletRequest = new MyHttpServletRequestWrapper(servletRequest); 

request.getInputStream () को केवल एक बार पढ़ने की अनुमति है इस पद्धति का कई बार उपयोग करने के लिए, हमें एचटीटीपीएसर्वेटरेक्स्टस्ट्रैप क्लास को कस्टम कार्य करने की आवश्यकता है। नीचे मेरा नमूना आवरण वर्ग देखें

 public class MultiReadHttpServletRequest extends HttpServletRequestWrapper { private ByteArrayOutputStream cachedBytes; public MultiReadHttpServletRequest(HttpServletRequest request) { super(request); } @Override public ServletInputStream getInputStream() throws IOException { if (cachedBytes == null) cacheInputStream(); return new CachedServletInputStream(); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } private void cacheInputStream() throws IOException { /* * Cache the inputstream in order to read it multiple times. For convenience, I use apache.commons IOUtils */ cachedBytes = new ByteArrayOutputStream(); IOUtils.copy(super.getInputStream(), cachedBytes); } /* An inputstream which reads the cached request body */ public class CachedServletInputStream extends ServletInputStream { private ByteArrayInputStream input; public CachedServletInputStream() { /* create a new input stream from the cached request body */ input = new ByteArrayInputStream(cachedBytes.toByteArray()); } @Override public int read() throws IOException { return input.read(); } } } 

मेरे मामले में, मैं लॉग इन में सभी आवक अनुरोधों का पता लगाता हूं। मैंने एक फ़िल्टर बनाया है

सार्वजनिक वर्ग TracerRequestFilter लागू करता है {निजी स्थिर अंतिम लॉगर LOG = LoggerFactory.getLogger (TracerRequestFilter.class);

 @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { final HttpServletRequest req = (HttpServletRequest) request; try { if (LOG.isDebugEnabled()) { final MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(req); // debug payload info logPayLoad(wrappedRequest); chain.doFilter(wrappedRequest, response); } else { chain.doFilter(request, response); } } finally { LOG.info("end-of-process"); } } private String getRemoteAddress(HttpServletRequest req) { String ipAddress = req.getHeader("X-FORWARDED-FOR"); if (ipAddress == null) { ipAddress = req.getRemoteAddr(); } return ipAddress; } private void logPayLoad(HttpServletRequest request) { final StringBuilder params = new StringBuilder(); final String method = request.getMethod().toUpperCase(); final String ipAddress = getRemoteAddress(request); final String userAgent = request.getHeader("User-Agent"); LOG.debug(String.format("============debug request==========")); LOG.debug(String.format("Access from ip:%s;ua:%s", ipAddress, userAgent)); LOG.debug(String.format("Method : %s requestUri %s", method, request.getRequestURI())); params.append("Query Params:").append(System.lineSeparator()); Enumeration<String> parameterNames = request.getParameterNames(); for (; parameterNames.hasMoreElements();) { String paramName = parameterNames.nextElement(); String paramValue = request.getParameter(paramName); if ("password".equalsIgnoreCase(paramName) || "pwd".equalsIgnoreCase(paramName)) { paramValue = "*****"; } params.append("---->").append(paramName).append(": ").append(paramValue).append(System.lineSeparator()); } LOG.debug(params.toString()); /** request body */ if ("POST".equals(method) || "PUT".equals(method)) { try { LOG.debug(IOUtils.toString(request.getInputStream())); } catch (IOException e) { LOG.error(e.getMessage(), e); } } LOG.debug(String.format("============End-debug-request==========")); } @Override public void init(FilterConfig arg0) throws ServletException { } 

}

यह मेरे लिए 2.5 और 3.0 सर्विसलेट दोनों काम करता है मैं सभी अनुरोध पैरामीटर को फ़ॉर्म-एन्कोडेड और जेसनस बॉडी का अनुरोध करता हूं।