Весна: як мені ввести HttpServletRequest у бін із масштабом запиту?


95

Я намагаюся налаштувати боб з обсягом запитів навесні.

Я успішно налаштував його, тому компонент створюється один раз на запит. Тепер йому потрібно отримати доступ до об’єкта HttpServletRequest.

Оскільки компонент bean створюється один раз на запит, я вважаю, що контейнер може легко ввести об'єкт запиту в мій компонент. Як я можу це зробити?

Відповіді:


114

Фасолі, охоплені запитом, можуть бути автоматично підключені до об'єкта запиту.

private @Autowired HttpServletRequest request;

2
Чи існує для цього старомодний XML-спосіб?
cherouvim

2
Не працює у мене (spring mvc 3.1) - можливо, є щось більше, що потрібно зробити? Йдемо з рішенням Саміта.
kldavis4

2
Проблема полягає в тому, що під час тестування валідаторів за допомогою MockMvc та такого роду ін’єкцій у вас будуть проблеми. Можливо, інше рішення буде кращим у цьому випадку
Нейко

21
Можна також підключити HttpServletRequest до непрофільних запитів, оскільки для HttpServletRequest Spring буде створено проксі HttpServletRequest, який знає, як отримати фактичний екземпляр запиту. Отже, безпечно запрошувати автоматичне підключення дроту, навіть якщо ваш контролер має одномісний масштаб.
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який реалізує інтерфейс.


Весняний Javadoc: RequestContextHolder | ServletRequestAttributes


8
Ін’єкція - це хороша роздільна здатність, але я виявив проблеми з MockMvc тестуванням валідаторів Spring, які вводять HttpServletRequest. Отже, якщо ви хочете, щоб і пробні тести, і виробничий код працювали належним чином, це повинен бути вибір.
Нейко

@Neyko Чому це? для макетного тесту (Unit test?), ви можете ввести макет HttpServletRequest або що завгодно .. чи не так? Або ви можете використовувати MockHttpServletRequest, я думаю?
Вінхі

Чи безпечно використовуватись в екземплярі сервісу, що охоплює єдине поле?
Джин Квон

2

Як пропонується тут, ви також можете ввести HttpServletRequestпараметр методу, наприклад:

public MyResponseObject myApiMethod(HttpServletRequest request, ...) {
    ...
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.