Мне нужно получить объект запроса в Java-коде. Я не могу передать этот объект до моего кода по определенным причинам. Есть ли способ сказать что-то вроде: getCurrentHTTPServletRequest
?
Для меня безопасно предположить, что я в контексте сервлета.
Мне нужно получить объект запроса в Java-коде. Я не могу передать этот объект до моего кода по определенным причинам. Есть ли способ сказать что-то вроде: getCurrentHTTPServletRequest
?
Для меня безопасно предположить, что я в контексте сервлета.
Хорошо, вам нужно сдать его, если вам это нужно. Все, что вы делаете, будет уродливо, в основном.
Вы можете использовать переменную ThreadLocal
- в основном задавать контекст для этого конкретного потока при получении запроса, а затем извлекать его позже на. Это будет работать, пока вам нужно только получить запрос в потоке, который его обрабатывает, и до тех пор, пока вы не будете заниматься фанкой асинхронной обработкой запросов. Это хрупкое, хотя именно по этим причинам.
Тем не менее, я настоятельно рекомендую вам четко указать ваши зависимости. Либо передайте запрос сервлета, либо просто нужные вам биты.
Предполагая, что вы не можете передать объект запроса в стек вызовов, тогда необходим какой-то механизм обмена, что не является идеальным, но иногда необходимым.
Spring предоставляет RequestContextFilter для просто эта цель. Он использует ThreadLocal
и позволяет коду извлекать текущий запрос через RequestContextHolder. Обратите внимание, что этот фильтр не требует использования какой-либо другой части Spring:
Сервл 2.3 Фильтр, который предоставляет запрос к текущему потоку, через как LocaleContextHolder, так и RequestContextHolder. Чтобы зарегистрироваться как фильтр в web.xml.
Этот фильтр используется в основном для использования с сторонние сервлеты, например. JSF FacesServlet. В пределах Spring собственной сети поддержка, DispatcherServlet's обработка вполне достаточна.
Если вы собираетесь использовать ThreadLocal
, тогда лучше использовать существующее, работающее решение, а не рисковать ошибки, в которых код ThreadLocal
подвержен.
Для этого нет API сервлета. Однако Tomcat предоставляет вызов API для этого,
HttpServletRequest request = (HttpServletRequest)org.apache.catalina.core.ApplicationFilterChain.getLastServicedRequest();
Это позволит получить последний запрос, переданный сервлету для обслуживания из текущего потока.
Чтобы это сработало, Tomcat должен находиться в режиме "Строгое соответствие сервлета". Если нет, вы должны включить его, добавив этот параметр JVM:
org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true
HttpServletRequest
, pass request.getParameterMap()
.
И добавив бит в параметр ThreadLocal
- вы можете иметь Filter
, который обрабатывает все входящие запросы, и устанавливает запрос в
public final static ThreadLocal<HttpServletRequest> httpServletRequestTL =
new ThreadLocal<HttpServletRequest>();
Поскольку вы настраиваете его для каждого запроса (осторожно с отображением фильтра), вам не придется беспокоиться о пуле потоков сервлетов-контейнеров - вы всегда будете иметь текущий запрос.
P.S. это логика утилиты spring, предложенная скаффманом - я присоединяюсь к нему, рекомендуя стабильный компонент, а не создавая свой собственный.
Предполагая, что сервлет верхнего уровня действительно является табу для какой-то сумасшедшей причины, связанной с бизнесом, все еще существует возможность определить ServletFilter
для предварительного просмотра запроса и заполнения его в ThreadLocal. Предполагая, что web.xml
также не является священным.
Но я согласен с Джоном Скитом в том, что это было бы очень уродливо. Я бы закодировал это, а затем попытался найти другую работу.:)
Собственно, учитывая тот факт, что фильтр может полностью вырвать управление из принимающего сервлета, вы можете использовать эту технику для переадресации кода на свой собственный сервлет, делать все, что захотите, и THEN запускать другой "официальный" "сервлет... или что-то еще в этом направлении. Некоторые из этих решений позволят вам правильно и надежно обрабатывать ваши данные запроса.