Подтвердить что ты не робот

Получить объект HttpServletRequest (запрос) из кода Java

Мне нужно получить объект запроса в Java-коде. Я не могу передать этот объект до моего кода по определенным причинам. Есть ли способ сказать что-то вроде: getCurrentHTTPServletRequest?

Для меня безопасно предположить, что я в контексте сервлета.

4b9b3361

Ответ 1

Хорошо, вам нужно сдать его, если вам это нужно. Все, что вы делаете, будет уродливо, в основном.

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

Тем не менее, я настоятельно рекомендую вам четко указать ваши зависимости. Либо передайте запрос сервлета, либо просто нужные вам биты.

Ответ 2

Предполагая, что вы не можете передать объект запроса в стек вызовов, тогда необходим какой-то механизм обмена, что не является идеальным, но иногда необходимым.

Spring предоставляет RequestContextFilter для просто эта цель. Он использует ThreadLocal и позволяет коду извлекать текущий запрос через RequestContextHolder. Обратите внимание, что этот фильтр не требует использования какой-либо другой части Spring:

Сервл 2.3 Фильтр, который предоставляет запрос к текущему потоку, через как LocaleContextHolder, так и RequestContextHolder. Чтобы зарегистрироваться как фильтр в web.xml.

Этот фильтр используется в основном для использования с сторонние сервлеты, например. JSF FacesServlet. В пределах Spring собственной сети поддержка, DispatcherServlet's обработка вполне достаточна.

Если вы собираетесь использовать ThreadLocal, тогда лучше использовать существующее, работающее решение, а не рисковать ошибки, в которых код ThreadLocal подвержен.

Ответ 3

Для этого нет API сервлета. Однако Tomcat предоставляет вызов API для этого,

HttpServletRequest request = (HttpServletRequest)org.apache.catalina.core.ApplicationFilterChain.getLastServicedRequest(); 

Это позволит получить последний запрос, переданный сервлету для обслуживания из текущего потока.

Чтобы это сработало, Tomcat должен находиться в режиме "Строгое соответствие сервлета". Если нет, вы должны включить его, добавив этот параметр JVM:

org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true

Ответ 4

Джон Скит сказал практически все, но одно пояснение к его совету "только то, что вам нужно" - если вам нужны ваши параметры запроса, переданные вниз, но вам не нужна зависимость от HttpServletRequest, pass request.getParameterMap().

И добавив бит в параметр ThreadLocal - вы можете иметь Filter, который обрабатывает все входящие запросы, и устанавливает запрос в

public final static ThreadLocal<HttpServletRequest> httpServletRequestTL =
      new ThreadLocal<HttpServletRequest>();

Поскольку вы настраиваете его для каждого запроса (осторожно с отображением фильтра), вам не придется беспокоиться о пуле потоков сервлетов-контейнеров - вы всегда будете иметь текущий запрос.

P.S. это логика утилиты spring, предложенная скаффманом - я присоединяюсь к нему, рекомендуя стабильный компонент, а не создавая свой собственный.

Ответ 5

Предполагая, что сервлет верхнего уровня действительно является табу для какой-то сумасшедшей причины, связанной с бизнесом, все еще существует возможность определить ServletFilter для предварительного просмотра запроса и заполнения его в ThreadLocal. Предполагая, что web.xml также не является священным.

Но я согласен с Джоном Скитом в том, что это было бы очень уродливо. Я бы закодировал это, а затем попытался найти другую работу.:)

Собственно, учитывая тот факт, что фильтр может полностью вырвать управление из принимающего сервлета, вы можете использовать эту технику для переадресации кода на свой собственный сервлет, делать все, что захотите, и THEN запускать другой "официальный" "сервлет... или что-то еще в этом направлении. Некоторые из этих решений позволят вам правильно и надежно обрабатывать ваши данные запроса.