Путаница в отношении поведения объекта запроса

Я возился с сервлетами и JSP, и я немного смущен чем-то:

  • Я сделал сервлет (контроллер), который отправил бы запрос в JSP

  • Я установил некоторые атрибуты объекта запроса, используя метод setAttribute() в моем сервлета.

  • Я могу получить доступ к параметрам и атрибутам объекта запроса в JSP без каких-либо проблема.

  • Теперь я сохранил объект запроса как атрибут в объекте сеанса, используя session.setAttribute( "тест", запрос).

  • Я написал второй JSP (переход к нему с первого JSP будет через Javascript при нажатии определенной кнопки - с помощью функции window.location и
    указывая адрес второго JSP в качестве значения)

  • Во втором JSP, когда я извлекаю объект запроса из объекта сеанса, я получаю файл null значение из всех атрибутов полученного объекта запроса.
  • Я могу получить доступ к параметрам возвращаемого объекта запроса, но только если бы я получил параметры по крайней мере один раз в моем первом JSP, используя метод request.getParameter()
    в противном случае они возвращают значение null в моем втором JSP.

Я действительно новичок в этом, и я смущен этим поведением. Почему атрибуты объекта запроса были "стерты", пока параметры остаются неповрежденными (как только я получил доступ к параметрам в моем первом JSP, что еще более сбивает меня с толку, так как это не имеет смысла ИМО)

Любое объяснение будет оценено! Благодарим вас заранее.

Ответ 1

Это всего лишь образованная догадка, но я думаю, что проблема заключается в том, что объекты запроса в выбранном вами контейнере могут лениться в отношении своих параметров: когда вы запрашиваете у него параметр, он обращается к внешнему контексту и извлекает требуемые данные, в то же время кэшируя его.

Тем не менее, причина странного поведения не очень важна. Проблема должна быть решена с помощью не сохранять запросы в сеансе. Объект запроса - это только ваш дескриптор текущего запроса, а не хранилище данных сам по себе. Он может использовать любой механизм под ним, поскольку все мы знаем, что атрибуты могут храниться в threadlocals. Нет абсолютно никакого контракта, который бы сделал запрос действительным архивом любого рода. Например: что бы это значило, если бы я спросил такой сохраненный запрос для принципала безопасности? Я имею в виду "текущий руководитель сессии"? Я хотел бы сказать "директор с момента создания запроса"?

EDIT:

Из чистого любопытства я просто заглянул в реализацию Tomcat (я понятия не имею, какой контейнер вы используете) и обнаружил, что он поддерживает мои претензии: не только большая часть данных собирается лениво, но и объект запроса перерабатывается! Поэтому, если вы попытаетесь сохранить его в сеансе, а затем использовать, вы можете обнаружить, что используете другой запрос.

Ответ 2

В Java EE 5 существует 4 области. В Java EE 6 и Java EE 7 там 5 областей. Наиболее часто используются:

  • Область запроса
  • Область сеанса
  • Область приложения (веб-контекст)

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

Вот цитата из документов API Java EE, связанных с метод ServletRequest.setAttribute(String, Object) в отношении область запроса:

void setAttribute(java.lang.String name,
                  java.lang.Object o)

Сохраняет атрибут в этом запросе. Атрибуты reset между Запросы. Этот метод чаще всего используется в сочетании с RequestDispatcher.
...

Таким образом, с каждым новым запросом будут потеряны предыдущие атрибуты, которые вы указали в запросе. После того как вы установили атрибут в запросе, вы должны переслать запрос на нужную страницу. Если вы перенаправляете, это будет абсолютно НОВЫЙ запрос, поэтому ранее установленные атрибуты будут потеряны. (Если вы все еще хотите использовать перенаправление, прочтите следующее: Перенаправление сервлетов на ту же страницу с сообщением об ошибке)

Те атрибуты, которые установлены в HttpSession (в области сеанса), будут жить до тех пор, пока и, конечно же, будет доступен только пользователю, которому принадлежит сессия.

Что касается атрибутов контекста, они должны быть доступны для всего веб-приложения (область приложения) и для ВСЕХ пользователей, плюс они живут до тех пор, пока веб-приложение живет.


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

Надеюсь, это поможет вам.

P.S.
Возможно, эта статья также будет полезна для вас: Как области Java EE 6 влияют на взаимодействие пользователей
Единственное, что в этой статье использует Annotations for scoping, но вы получите эту идею.