Я пытаюсь записать тело запроса со встроенного причала-сервера.
Успешно получаю тело POST-запроса (в основном от https://stackoverflow.com/a/19547549/8916463 и 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() {}
}
}
Проблема в том, что при такой настройке сервера POST-запросы от контроллеров вообще не вызываются. Но они правильно вызываются, когда я пытаюсь вести журнал с использованием журнала NCSA (в этом случае тело запроса не регистрируется):
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);
Мой Цель - записывать тело запроса в какой-то файл.
Видимо мне не хватает чего-то очень простого, и логирование тела запросов можно реализовать намного проще.
PS. Пружина не используется.
Любая помощь будет глубоко оценена!
Не могли бы вы указать ограничения на использование Servlet 3.1 с оболочками? Теперь проблема в том, что после фильтрации (методы doGet, doPost) запрос вообще не перенаправляется на соответствующие методы контроллера.
Со старыми обертками (около Servlet 2.x) вы теряете возможность использовать функции Async в Servlet 3.x, а также увеличиваете конкуренцию в сети, увеличиваете конкуренцию пула потоков и увеличиваете использование памяти.
Многие современные и актуальные библиотеки Java с открытым исходным кодом, которые используют API сервлетов, избавляются от своих оболочек за последние несколько лет. Их осталось мало, у всех есть нерешенные вопросы по их удалению.
Хорошо понял. Не могли бы вы также указать причину, по которой методы контроллера не вызываются после перехвата с помощью doFilter / doPost? (что для меня совершенно нелогично) Другими словами, как вызвать оригинальные методы отдыха с включенной фильтрацией?
Пожалуйста, задайте для этого новый вопрос. Для ответа нужны подробности.
Я уже уточнил все детали, которые у меня есть в этом вопросе, основная часть которых до сих пор остается без ответа. В основном мне нужен только один рабочий пример, где реализовано ведение журнала (в какой-либо файл) тела запроса и запросы после регистрации правильно вызываются. Я искал здесь десятки тем, но не нашел ничего работающего (не в Spring).




Только 1 фрагмент кода может прочитать содержимое тела запроса, это либо ваша структура фильтров / ведения журнала, либо ваш сервлет. Вам нужно будет выбрать один. (Остерегайтесь тех, кто говорит о создании оболочек для HttpServletRequest или InputStream, поскольку эти методы серьезно ограничивают вашу способность использовать Servlet 3.1)