简体   繁体   中英

Log request body for jersey client 1.18.1

I'm using JEE6 (on server, can't change it) with Jersey client 1.18.1, and I want to log all HTTP get/post request/response into DB (in String format) and I use ClientFilter to intercept.

For response, i can copy resp.getEntityInputStream() with IOUtils , then convert back to string.

But for request, there's no ' getEntityInputStream ' for it and it'll quite a lot of work to cater with different types - string, form, jaxb etc

So my question is, is there a easier way to handle this in Jersery Client? If not, is there any other framework/tools that can help?

You want to intercept this beforehand whilst it's still a string. However you can only obtain it once, so need to keep it around to provide to anything else which needs it.

Here are the main pieces of a body prefetch filter, taken from an existing codebase . Note that if you're going to log to a database you might want to decouple that from the request stream, perhaps by posting the body on a message bus and having a separate process carry out logging, to avoid every request having to wait for a database write.

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);
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM