Struts и логирование HTTP POST-запроса - PullRequest
1 голос
/ 15 марта 2010

Я пытаюсь зарегистрировать необработанное тело HTTP-запросов POST в нашем приложении на основе Struts, работающем на Tomcat 6. Я нашел один предыдущий пост на SO, который был несколько полезен, но принятое решение не работает должным образом в моем случае. Проблема в том, что я хочу регистрировать тело POST только в определенных случаях, и позволяют Struts анализировать параметры из тела после регистрации. В настоящее время в фильтре, который я написал, я могу читать и регистрировать тело из объекта HttpServletRequestWrapper, но после этого Struts не может найти какие-либо параметры для анализа, поэтому вызов DispatchAction (который зависит от одного из параметров из запроса) завершается неудачно.

Я немного покопался в исходном коде Struts и Tomcat и обнаружил, что не имеет значения, сохраню ли я тело POST в байтовом массиве и выставлю Stream и Reader на основе этого массива; когда параметры должны быть проанализированы, объект запроса Tomcat получает доступ к своему внутреннему InputStream, который к тому времени уже был прочитан.

У кого-нибудь есть идеи, как правильно реализовать этот вид журналирования?

Ответы [ 3 ]

2 голосов
/ 21 марта 2010

Фактически, Struts не анализирует параметры, для этого он использует контейнер Servlet. И как только контейнер прочитал inputStream для создания параметров Map, конечно, больше нечего читать. А в реализации Tomcat, если вы сначала читаете inputStream, то семейству методов getParameter * больше нечего работать, поскольку, как вы правильно заметили, он не использует getInputStream или getReader, а обращается к своему оптимизированному считывателю внутри. Таким образом, ваше единственное решение в вашем ServletRequestWrapper - переопределить getInputStream, getReader и семейство getParameter *, для которого Struts полагается на чтение параметров. Возможно, вы можете взглянуть на org.apache.catalina.util.RequestUtil, чтобы не дублировать часть разбора тела POST.

0 голосов
/ 15 марта 2010

Пример фильтра со связанными вопросами выглядит хорошо и должен работать. Возможно, вы определяете его в web.xml после фильтра диспетчера Struts. Тогда было бы действительно слишком поздно проанализировать и зарегистрировать тело запроса и все же сделать его доступным для Struts. Вам необходимо объявить этот фильтр до фильтра диспетчера Struts. Порядок фильтров имеет значение, они вызываются в том порядке, в котором они определены в web.xml.

0 голосов
/ 15 марта 2010

Что вы должны сделать в своем фильтре, так это прочитать содержимое сообщения полностью, а затем, когда вы собираетесь передать запрос в цепочку; верните поток ввода своим собственным. Например, вы читаете запись в файл на диске, а затем при вызове:

chain.doFilter(new ServletRequest() {}, response);

Вы можете делегировать большинство вызовов методов вашего класса исходному запросу, но когда приходит время открывать входной поток, вам нужно прочитать файл на диске.

Вам необходимо убедиться, что вы не утечки ресурсов, так как это будет вызываться довольно часто и может причинить вред, если сделано неправильно.

...