我在Jersey客户端1.18.1上使用JEE6(在服务器上,无法更改),我想将所有HTTP get / post请求/响应记录到DB中(以String格式)和我使用ClientFilter来拦截。
对于回复,我可以使用 IOUtils 复制resp.getEntityInputStream()
,然后转换回字符串。
但是根据要求,没有' getEntityInputStream
'对于它而言,它需要做很多工作来满足不同的类型 - 字符串,形式,jaxb等
所以我的问题是,在Jersery客户端中有更简单的方法来处理这个问题吗?如果没有,是否有其他框架/工具可以提供帮助?
答案 0 :(得分:-1)
你想要预先拦截它,而它仍然是一个字符串。但是你只能获得一次,所以需要保留它以提供其它任何需要它的东西。
以下是正文预取过滤器的主要部分,取自an existing codebase。请注意,如果您要登录到数据库,您可能希望将其与请求流分离,可能是通过在消息总线上发布正文并让单独的进程执行日志记录,以避免每个请求都必须等待用于数据库写入。
public class BodyPrefetchFilter implements Filter
{
private static final Logger LOGGER = LoggerFactory.getLogger(BodyPrefetchFilter.class);
@Override
public void init(final FilterConfig filterConfig) throws ServletException {}
@Override
public void destroy() {}
@Override
public void doFilter(final ServletRequest servletRequest,
final ServletResponse servletResponse,
final FilterChain chain) throws IOException, ServletException
{
HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse)servletResponse;
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpServletRequest);
chain.doFilter(bufferedRequest, httpServletResponse);
}
private static final class BufferedRequestWrapper extends HttpServletRequestWrapper
{
private byte[] body = null;
public BufferedRequestWrapper(HttpServletRequest req) throws IOException
{
super(req);
// Store the body
final InputStream is = req.getInputStream();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buf)) > 0)
{
baos.write(buf, 0, bytesRead);
}
this.body = baos.toByteArray();
if (this.body.length > 0)
{
LOGGER.debug("Body of request is \"{}\"", new String(this.body, "UTF-8"));
}
}
@Override
public ServletInputStream getInputStream()
{
ByteArrayInputStream bais = new ByteArrayInputStream(this.body);
return new BufferedServletInputStream(bais);
}
}
private static final class BufferedServletInputStream extends ServletInputStream
{
private final ByteArrayInputStream inputStream;
public BufferedServletInputStream(final ByteArrayInputStream inputStream)
{
this.inputStream = inputStream;
}
@Override
public int available()
{
return this.inputStream.available();
}
@Override
public int read()
{
return this.inputStream.read();
}
@Override
public int read(final byte[] buf, final int off, final int len)
{
return this.inputStream.read(buf, off, len);
}
}
}