REST-запросы не обрабатываются после входа во встроенную Jetty 9.4.12

Я пытаюсь записать тело запроса со встроенного причала-сервера.

Успешно получаю тело 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. Пружина не используется.

Любая помощь будет глубоко оценена!

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

Joakim Erdfelt 09.10.2018 15:40

Не могли бы вы указать ограничения на использование Servlet 3.1 с оболочками? Теперь проблема в том, что после фильтрации (методы doGet, doPost) запрос вообще не перенаправляется на соответствующие методы контроллера.

Egor Erofeev 09.10.2018 15:56

Со старыми обертками (около Servlet 2.x) вы теряете возможность использовать функции Async в Servlet 3.x, а также увеличиваете конкуренцию в сети, увеличиваете конкуренцию пула потоков и увеличиваете использование памяти.

Joakim Erdfelt 09.10.2018 15:57

Многие современные и актуальные библиотеки Java с открытым исходным кодом, которые используют API сервлетов, избавляются от своих оболочек за последние несколько лет. Их осталось мало, у всех есть нерешенные вопросы по их удалению.

Joakim Erdfelt 09.10.2018 15:59

Хорошо понял. Не могли бы вы также указать причину, по которой методы контроллера не вызываются после перехвата с помощью doFilter / doPost? (что для меня совершенно нелогично) Другими словами, как вызвать оригинальные методы отдыха с включенной фильтрацией?

Egor Erofeev 09.10.2018 16:02

Пожалуйста, задайте для этого новый вопрос. Для ответа нужны подробности.

Joakim Erdfelt 09.10.2018 16:05

Я уже уточнил все детали, которые у меня есть в этом вопросе, основная часть которых до сих пор остается без ответа. В основном мне нужен только один рабочий пример, где реализовано ведение журнала (в какой-либо файл) тела запроса и запросы после регистрации правильно вызываются. Я искал здесь десятки тем, но не нашел ничего работающего (не в Spring).

Egor Erofeev 09.10.2018 16:16
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
66
0

Другие вопросы по теме