java 多次 httprequest_java - 如何多次读取request.getInputStream() - 堆栈内存溢出

request.getInputStream()只能读取一次。 为了多次使用此方法,我们需要对HttpServletReqeustWrapper类进行额外的自定义任务。 请参阅下面的示例包装器类。

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实现了Filter {私有静态最终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 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 {

}

}

它对我来说都适用于Servlet 2.5和3.0。 我看到所有请求参数都经过形式编码和请求json主体。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值