SendRedirect () сервлета убивает мои атрибуты сеанса - PullRequest
9 голосов
/ 06 ноября 2011

Я работаю над веб-приложением в WinXP, Eclipse Indigo и веб-плагине Google.

У меня есть простая форма, которая принимает значение от пользователя (например, по электронной почте), передает его сервлету с именем SignIn.javaкоторый обрабатывает его и сохраняет значение электронной почты в сеансе.Код SignIn очень прост, вот что его doGet в основном делает:

String email = req.getParameter("email");   //getting the parameter from html form
...
...
HttpSession session = req.getSession();     //create a new session
session.setAttribute("email", email);

Пока все хорошо, я убедился, что значения не равны null на данный момент.Теперь возникает проблема, я хочу перенаправить на другой сервлет (ShowOnline.java), который должен сделать еще немного обработки.Когда я пишу

resp.sendRedirect(resp.encodeRedirectURL("/ShowOnlineServlet")); 

ShowOnline получает null значения сеанса (тот же атрибут электронной почты, который я сохранил секунду назад, теперь null)

Когда я пишу

getServletConfig().getServletContext().getRequestDispatcher("/ShowOnlineServlet");

все в порядке, атрибут электронной почты ранее не null!

Что происходит?sendRedirect() просто заставляет ваш браузер отправлять новый запрос, это не должно влиять на объем сеанса.Я проверил файлы cookie, и они в порядке (это точно тот же сеанс, что и раньше, поскольку это первый и единственный сеанс, который создает мое веб-приложение, и, кроме того, я даже потрудился и проверил идентификаторы sesison, и они одинаковы в обоих запросах).

Почему существует разница между sendRedirect() и forward()?Простым решением было бы использовать forward(), но я хочу докопаться до этого, прежде чем просто отпустить, я думаю, что для меня важно понять, что произошло.Я не уверен, что мне нравится идея не знать, что происходит с такими базовыми понятиями (все мое веб-приложение очень простое и базовое на данный момент, так как я начинающий).

Любые мысли, идеи или предложениябудет тепло приветствоваться!

Ответы [ 2 ]

1 голос
/ 03 декабря 2011

Если ваш SignIn сервлет сохраняет только параметр запроса (электронная почта), то вы также можете заменить сервлет на фильтр , например. SignInFilter.

SignInFilter будет содержать ту же логику, что и ваш сервлет SignIn (копирование электронной почты из параметров запроса в сеанс), но вместо этого вызовет следующий элемент в цепочке (который будет вашим ShowOnline сервлетом) делать любое перенаправление / вперед.

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
    throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession();

    String email = req.getParameter("email");
    session.setAttribute("email", email);

    chain.doFilter(req, res); // continue to 'ShowOnline'

}

Вместо этого установите в POST форму сервлета ShowOnline и настройте свой новый SignInFilter для выполнения до ShowOnline (для краткости отображение сервлета опущено ниже).

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <filter>
        <filter-name>SignInFilter</filter-name>
        <filter-class>com.example.SignInFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SignInFilter</filter-name>
        <url-pattern>/ShowOnline</url-pattern>
    </filter-mapping>
</web-app>
0 голосов
/ 12 января 2012

Насколько мне известно, sendRedirect () просто перенаправляет элемент управления на другую страницу, не передавая связанный объект запроса и ответа родительской страницы, но RequestDispatcher (объект) отправит ServletRequest и ServletResponse на страницу, указанную в аргументе пути { getServletContext (). getRequestDispatcher ("path")} после этого вы можете либо перенаправить объекты на эту страницу, либо включить объекты. Таким образом, этот контейнер становится уверенным, что он должен использовать предыдущий объект запроса и ответа от родительской страницы вместо создания новой. Особенно, если вы используете управление сеансами, лучшим вариантом является RequestDispatcher.

Надеюсь, что ответит на вопрос.

Всем: - Пожалуйста, поправьте меня, если я ошибаюсь.

@ RS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...