Spring: как мне внедрить HttpServletRequest в bean-компонент с областью действия запроса?


96

Я пытаюсь настроить компонент с ограниченным объемом запроса весной.

Я успешно настроил его, поэтому компонент создается один раз для каждого запроса. Теперь ему нужно получить доступ к объекту HttpServletRequest.

Поскольку компонент создается один раз за запрос, я полагаю, что контейнер может легко внедрить объект запроса в мой компонент. Как я могу это сделать ?

Ответы:


115

Компоненты с областью действия запроса могут быть автоматически связаны с объектом запроса.

private @Autowired HttpServletRequest request;

2
Есть ли для этого старомодный способ XML?
cherouvim

2
У меня не работает (spring mvc 3.1) - может есть еще что-то, что нужно сделать? Собираюсь с решением Самита.
kldavis4 07

2
Проблема в том, что при тестировании валидаторов с использованием MockMvc и такого рода инъекций у вас будут проблемы.
Возможно,

21
Можно также автоматически подключать HttpServletRequest к bean-компонентам без области запроса, поскольку для HttpServletRequest Spring будет генерировать прокси-сервер HttpServletRequest, который знает, как получить фактический экземпляр запроса. Таким образом, запрос autowire безопасен, даже если ваш контроллер имеет одноэлементную область видимости.
vtor

3
Предупреждение для пользователей Spring <= 3.1: автоматическое подключение не будет работать при выполнении тестов.
Рубенс Мариуццо

138

Spring предоставляет текущий HttpServletRequestобъект (а также текущий HttpSessionобъект) через объект- оболочку типа ServletRequestAttributes. Этот объект-оболочка привязан к ThreadLocal и получается путем вызова staticметода RequestContextHolder.currentRequestAttributes().

ServletRequestAttributesпредоставляет метод getRequest()для получения текущего запроса, getSession()для получения текущего сеанса и других методов для получения атрибутов, хранящихся в обеих областях. Следующий код, хотя и немного уродливый, должен предоставить вам текущий объект запроса в любом месте приложения:

HttpServletRequest curRequest = 
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();

Обратите внимание, что RequestContextHolder.currentRequestAttributes()метод возвращает интерфейс и должен иметь тип ServletRequestAttributes, реализующий интерфейс.


Spring Javadoc: RequestContextHolder | ServletRequestAttributes


8
Инъекция - хорошее решение, но я обнаружил проблемы с проверкой MockMvc валидаторов Spring, которые вводят HttpServletRequest. Поэтому, если вы хотите, чтобы как тестовые тесты, так и производственный код работали правильно, это должен быть выбор.
Neyko

@Нейко Почему? для фиктивного теста (модульного теста?) вы можете ввести фиктивный HttpServletRequest или что угодно, не так ли? Или вы можете использовать MockHttpServletRequest, я думаю?
wonhee

Безопасно ли использовать в экземпляре службы с одноэлементной областью действия?
Джин Квон

2

Как предлагается здесь, вы также можете ввести HttpServletRequestкак параметр метода, например:

public MyResponseObject myApiMethod(HttpServletRequest request, ...) {
    ...
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.