1

I'm trying to log the request body from embedded jetty-server.

I successfully get the body of the POST-request (mainly from https://stackoverflow.com/a/19547549/8916463 and https://stackoverflow.com/a/8972088/8916463)

public class JettyFilter {

  public static void main(final String[] args) throws Exception {
    Server server = new Server(8080);

    ServletHandler handler = new ServletHandler();
    server.setHandler(handler);

    handler.addServletWithMapping(HelloServlet.class, "/*");
    handler.addFilterWithMapping(WebServerLoggingFilter .class, "/*",
        EnumSet.of(DispatcherType.REQUEST));

    server.start();
    server.join();
  }

  public static class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException { 
            System.out.println(request.getReader().lines()
                    .collect(Collectors.joining(System.lineSeparator())));
    }
  }

public static class WebServerLoggingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        System.out.println("hello from filter");
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

    @Override
    public void destroy() {}
  }
}

The problem is that the POST-requests from the controllers are not called at all when I configure server this way. But they are properly called when I try logging using NCSA logging, (in such case request body is not logged):

NCSARequestLog requestLog = new NCSARequestLog(os.getDatedFilename());
requestLog.setExtended(true);
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
requestLog.setAppend(true);

HandlerList mainHandlers = new HandlerList();
mainHandlers.addHandler(accessHandler);
mainHandlers.addHandler(new DefaultHandler());

requestLogHandler.setHandler(mainHandlers);
HandlerList topLevelHandlers = new HandlerList();
topLevelHandlers.addHandler(requestLogHandler);

server.setHandler(topLevelHandlers);

My goal is to log the body of the request to some file.

Apparently I miss something very simple and logging of the requests body can be implemented much easier.

PS. Spring is not used.

Any help will be deeply appreciated!

Egor Erofeev
  • 137
  • 1
  • 2
  • 15
  • Only 1 piece of code can read the request body content, it's either your filters/logging framework, or your servlet. You'll need to pick one. (Beware anyone that says to create wrappers for HttpServletRequest or it's InputStream, as those techniques will severely limit your ability to use Servlet 3.1) – Joakim Erdfelt Oct 09 '18 at 13:40
  • Could you specify the limitations of using Servlet 3.1 with wrappers? Now the issue is that after filtering(doGet, doPost methods) the request is not redirected to corresponding controller's methods at all. – Egor Erofeev Oct 09 '18 at 13:56
  • 1
    With old school wrappers (circa Servlet 2.x) you lose the ability to use Async features in Servlet 3.x, along with increasing network contention, increased thread pool contention, and increased memory usage. – Joakim Erdfelt Oct 09 '18 at 13:57
  • 1
    Many modern and up to date open source java libraries that use the Servlet API have been getting rid of their wrappers over the past few years. Few have them left, all of those have open issues to remove them. – Joakim Erdfelt Oct 09 '18 at 13:59
  • Ok, got it. Could you also specify the reason why contoller's methods are not called after being intercepted with doFilter/doPost? (which is completely counterintuitive to me) In other words how to get original rest-methods called with filtering enabled? – Egor Erofeev Oct 09 '18 at 14:02
  • Please ask a new question for that. It needs detail to answer. – Joakim Erdfelt Oct 09 '18 at 14:05
  • I've already specified all of details I have in this question the principal part of which is still unanswered. Basically I need just one working example where logging (to some file) of the request body is implemented and requests after logging are properly called. I have been searching through dozens of topic here but did not find anything working (not in Spring). – Egor Erofeev Oct 09 '18 at 14:16

0 Answers0