request.getInputStream () is allowed to read only once. To use this method many times, we need to perform an additional custom task for the HttpServletReqeustWrapper class. see my shell class sample below.
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 { cachedBytes = new ByteArrayOutputStream(); IOUtils.copy(super.getInputStream(), cachedBytes); } public class CachedServletInputStream extends ServletInputStream { private ByteArrayInputStream input; public CachedServletInputStream() { input = new ByteArrayInputStream(cachedBytes.toByteArray()); } @Override public int read() throws IOException { return input.read(); } } }
In my case, I keep track of all incoming requests to the log. I created a filter
the public class TracerRequestFilter implements Filter {private static final Logger 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 { } }
Both servlet 2.5 and 3.0 work for me. I see all the request parameters both in the encoding of the form and in the body of the json request.
sopheamak Oct 19 '17 at 7:00 2017-10-19 07:00
source share