Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> JSP — с чего начать? 
V
    Опции темы
diablero
Дата 23.7.2007, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Не, я не это имел ввиду.
template.vm это наш базовый шаблон. Где есть такая строчка
Код

<td id="content">#parse("$content")</td>

Мы запрашиваем статью, в воркере статьи, мы заполняем контескт и сливаем его с post.vm.
Теперь нам нужно слить post.vm с template.vm. Вот я не пойму как это сделать


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
Stampede
Дата 23.7.2007, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 66
Всего: 144



Так а это делается не сливанием в смысле merge. Просто когда движок Velocity дойдет до строчки #parse("$content"), он полезет в контекст, найдет там переменную "content", и использует ее как имя шаблона, который нужно включить в данном месте.

Как я уже говорил ранее, это забота воркера - заранее положить в контекст имя нужного шаблона:

Код

public class ArticleWorker extends AbstractWorker {
    public VelocityContext execute(HttpServletRequest request, HtpServletResponse response) {
        VelocityContext context = new VelocityContext();
        context.put("content", "article.vm");
        // ...
    }
}



--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
diablero
Дата 23.7.2007, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Вопрос снят. smile

Добавлено @ 22:28
А... Ту уже ответилsmile 
Сейчас все выложу



Релиз кандидат четвертой жЫрной черты

Это сообщение отредактировал(а) diablero - 25.7.2007, 20:21

Присоединённый файл ( Кол-во скачиваний: 117 )
Присоединённый файл  Infinite1.1.3.4.zip 23,88 Kb


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
Stampede
Дата 23.7.2007, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 66
Всего: 144



Поздравляю!

Разбор полетов - завтра. А пока - всем отдыхать smile

Да и мне бы еще по работе чуток поработать smile


--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
Stampede
Дата 24.7.2007, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 66
Всего: 144



Ну знач поехали.

1. Пора бы нам уже начать группировать классы по пакетам, а то куча уже большая получается. Напрмер, явно напрашиваются к выделению менеджеры, воркеры и data бины.

2. Есть несколько не совсем удачных имен, которые привносят путаницу.
  • Например, почему Configuration превратилось в Settings?
  • Или, например, интерфейс EngineManager. Я бы его вообще убрал, потому что он у нас недостаточно общий, поскольку имеет библиотечную зависимость, VelocityContext. Тут надо или вводить дополнительный слой абстракции для контекста, или отказываться от потуг сделать все в общем виде.
  • Имя MainController не отражает того факта, что это все-таки в первую очередь сервлет. ControllerServlet было бы лучше.
  • В web.xml для главного сервлета используется имя index.shtml. Это вводит в заблуждение, поскольку наводит на мысли о каких-то физических структурах.

3. Использование переменных в шаблоне.

Вот смотри, как у тебя сделан post.vm:

Код

<table>
<tr>
    <td>$user_name / $article_date  / <u>версия для печати</u></td>
</tr>
<tr>
    <td>$article_title</td>
</tr>
<tr>
    <td>$article_text</td>
</tr>
</table>



А ведь Velocity-то позволяет обращаться к полям бинов (имеющим соответствующие геттеры) напрямую! И получается, что нам всего-то нужно засунуть в контекст две переменные: user и article. Это резко сокращает вероятность ошибок типа недосмотров, опечаток и наложения имен. Шаблон будет выглядеть вот так:

Код

<table>
<tr>
    <td>$user.name / $article.date</td>
</tr>
<tr>
    <td>$article.title</td>
</tr>
<tr>
    <td>$article.text</td>
</tr>
</table>


Я убрал "версию для печати", потому что в наше время это делается гораздо проще, средствами CSS.

Ну и по-хорошему $user.name надо бы сделать ссылкой:

Код

<td><a href="$user.url">$user.name</a> / $article.date</td>


4. Ну и по мелочам:
  • В infinite.sql отсутствует часть для Section.
  • Код CSS надо все-таки как-то планировать, но это ладно, потом.
  • При выставлении contentType в методе service() кодировку лучше брать все-таки из конфига - мы ж его для этого и предусматривали.

Может, еще что замечу/вспомню. Предлагаю подкорректировать по своему усмотрению и перезалить.



--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
diablero
Дата 25.7.2007, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Создал бин News. И что бы не было путанницы, везде теперь фигурирует Post, а не Article. Классы по пакетам сгруппировал, может быть имя не совсем удачное выбрал?
Интерфейс EngineManager убрал, не думаю что откажусь от Velocity.
Еще посмотрю и проанализирую...
Перезалил.

Теперь уже вырисовыватся вполне ясная картина, и структура сайта. Рано или поздно я бы дошел до этого, или бы забил на пол путиsmile Т.к. не встречал ни одной книги, где разъяснялась последовательность разработки, даже простого сайта. Как закончим, нужно будет это все оформить, но это все потом.

З.Ы. Попутно научился засыпать раньше чем закроются глазаsmile



--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
Stampede
Дата 25.7.2007, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 66
Всего: 144



Цитата(diablero @  25.7.2007,  11:30 Найти цитируемый пост)
Теперь уже вырисовыватся вполне ясная картина, и структура сайта.


Да, и это заметно - например, по тому, как ты ловко добавил сущности Section и News, со всеми сопутствующими компонентами.

В целом структура кода уже почти окончательная. Единственное, мы немного изменим сигнатуру метода Worker.execute() и введем дополнительно несколько новых понятий - для пущего удобства. А сейчас приступаем к следующему этапу - аутентификации и авторизации доступа.

Как мы уже многократно убеждались, "книжные" подходы для нас, простых сайтостроителей, не годятся. Поэтому мы пойдем другим путем. А именно, возьмем на вооружение простую технику, веками используемую в мире ПХП - технику, основанную на куках. Для этого важно понимать, что такое куки, кем и когда они создаются, и как участвуют в коммуникации по HTTP. Чтобы иметь полную картину происходящего, рекомендуется скачать и установить плагин Firebug. Тогда на закладке Net будет видно, с точностью до буквы, что поылал браузер, и что приходило в ответ.

Итак, первым делом нам нужно залогиниться. Для этого где-нибудь в шапке страницы пропиши форму для ввода с полями login, password и кнопкой "Войти", метод POST. Атрибут action пусть указывает на такой УРЛ:

/submit/login.do

Здесь .do оправданно, поскольку это будет у нас невизуальный ресурс. Соответственно, для него надо будет прописать маппинг в web.xml (на ControllerServlet) и в диспетчере воркеров (на LoginWorker.class).

В воркере надо прочитать параметры запроса login и password, пробить их через UserManager, и положить в VelocityContext объект типа User. ПДалее показать факт успешного логина (или ошибки) через вставной подшаблон confirmation.vm.

Пока этого будет достаточно.



--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
diablero
Дата 25.7.2007, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Цитата(Stampede @  25.7.2007,  21:53 Найти цитируемый пост)
вставной подшаблон confirmation.vm

Как его воткнуть грамотно вв шапку страницы, подумаю завтра. А так проверил работоспособность, работает.
Код

public class LoginWorker extends AbstractWorker implements Worker{
    public VelocityContext execute(HttpServletRequest request, HttpServletResponse response) {
        VelocityContext context = new VelocityContext();
        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        Infinite infinite = Infinite.getInstance();
        UserManager manager = infinite.getUserManger();
        try {
            manager.login(userName,password);
            context.put("login_state", userName+" is login");
        } catch (Exception err) {
            context.put("login_state", err.getMessage());
        }
        context.put("content", "confirmation.vm");
        return context;
    }
}

template.vm
Код

...
<td align="left"><form action="/submit/login.do" method="post">User:&nbsp;<input type="Text" name="userName">&nbsp;Password: <input type="Password" name="password">&nbsp;<input type="Submit" value="Войти"></form></td>
...

web.xml
Код

<servlet-mapping>
        <servlet-name>ControllerServlet</servlet-name>
        <url-pattern>/submit/login.do</url-pattern>
    </servlet-mapping>




--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
Stampede
Дата 26.7.2007, 01:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 66
Всего: 144



Цитата(diablero @  25.7.2007,  11:30 Найти цитируемый пост)
Классы по пакетам сгруппировал, может быть имя не совсем удачное выбрал?


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


Цитата(diablero @  25.7.2007,  14:17 Найти цитируемый пост)

<servlet-mapping>
        <servlet-name>ControllerServlet</servlet-name>
        <url-pattern>/submit/login.do</url-pattern>
</servlet-mapping>


У нас еще много будет невизуальных обработчиков всяких сабмитов, и все они будут проходить через тот же сервлет-контроллер, так что имеет смысл задать маппинг по расширению *.do.

С формой более-менее все в порядке, с обработчиком тоже. Так что перейдем к следующей задаче: запоминанию. Но сначала обещанный рефакторинг.

Речь идет о возвращаемом значении метода execute(). Он имеет тип VelocityContext. Это не совсем удобно, ибо это весьма общий тип. Коль скоро мы имеем дело с представлением вебной страницы, хорошо было бы, чтобы оно предоставляло нам прямой доступ к ряду существенных вебных штучек. Поэтому я предлагаю завести класс (назовем его Page), наследующий от VelocityContext, примерно такого содержания:

Код

public class Page extends VelocityContext {
    private String redirectUrl;

    public Page(HttpServletRequest request, HttpServletResponse response) {
        put("request", request);
        put("response", response);
        put("url", request.getRequestURI());
    }

    // а также геттер и сеттер для redirectUrl
}


Соответственным образом изменится и сигнатура метода execute(). И вот что это нам сразу дает: мы сейчас легко и просто реализуем паттерн PRG (Post-Redirect-Get).

Пару слов о том, что это за паттерн и для чего он нужен. Если в ответ на сабмит формы возвращать отображаемый текст, то это чревато многими путаницами: например, если юзер решит походить кнопками браузера Взад/Вперед, или нажмет рефреш. Чтобы избежать этих неприятностей, есть достаточно простое решение: по сабмиту всегда возвращать HTTP код статуса 302 (ресурс временно перемещен), заодно в заголовке ответа Location указывается адрес для переадресации. В Servlet API для этой цели есть удобное сокращение: response.sendRedirect(String url);

Так вот, я предлагаю для всех обработчиков сабмитов выставлять переменную page.redirectUrl, а в коде сервлета ее анализировать и соответственно что-то делать. Возникает вопрос: а почему не вызывать sendRedirect() непосредственно в коде воркера? А потому, что в этом случае ответ сразу уйдет браузеру, а нам бы хотелось поманипулировать заголовками ответа, в том числе кукисами.

Итак, в LoginWorker пишем примерно так:

Код

protected Page page;
public Page execute(HttpServletRequest request, HttpServletResponse response) {
    public static final AGE_NINETY_DAYS = 3600 * 24 * 90; // 90 days in seconds
    page = new Page(request, response);
    // ...
    User user = userManager.login(userName, pasword);
    if (user != null) {
        page.put("user", user);
        Cookie cookie = new Cookie("userName", user.getName());
        cookie.setPath("/");
        cookie.setMaxAge(AGE_NINETY_DAYS);
        response.addCookie(cookie);
        cookie = new Cookie("password", user.getPassword());
        cookie.setPath("/");
        cookie.setMaxAge(AGE_NINETY_DAYS);
        response.addCookie(cookie);
        page.setRedirectUrl("/confirmation.shtml");
    } else {
        // строка внизу закомментрована, поскольку она нам ничего не дает:
        // после редиректа от нее ничего не останется. На самом деле
        // такие вещи надо делать через сессию, но мы пока об этом не будем.
        // page.put("message", "Invalid user name or pasword.");

        // тут по-хорошему нужно на всякий случай сбросить кукисы userName и password
        // на клиенте, но мы щас не будем загромождать код
        page.setRedirectUrl("/login.shtml");
    }
}


Вообще надо сказать, работа с куками в Servlet API сделана очень неудачно - приходится делать много лишних телодвижений для реализации самых простых вещей. Выходом может быть написание собственных удобных функций. Например, мы могли бы в Page предусмотреть очень простой метод setLongLivedCookie(String name, String value), и то, что мы тут делали в четыре строки, делалось бы в одну. Аналогичным образом можно было бы написать метод resetCookie(String name). Впрочем, все это со времени мы и сделаем.

Не забываем, что в сервлете-контроллере мы должны проверить значение переменной redirectUrl:

Код

public void service(...) throws ... {
    // ...
    Page page = worker.execute(request, response);
    if (page.getRedirectUrl() != null) {
        response.sendRedirect(page.getRedirectUrl());
    } else {
        Writer writer = response.getWriter();
        // ...
    }
}


Теперь смотри, diablero: мы сейчас опять применим объектный подход и снова разом упростим структуру кода.

Юзера нам надо определять при каждом входящем запросе, потому что от этого зависит, что показывать, что не показывать, и показывать ли вообще. Чтобы не дублировать код чтения кукисов во всех воркерах, мы в базовом AbstractWorker можем написать такое:

Код

public abstract class AbstractWorker implements Worker {
    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected Page page;
    protected User user;
    // ...
    public Page execute(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        page = new Page(request, response);

        Cookie[] cookies = request.getCookies();
        // тут мы каким-то образом получаем интересующие нас кукисы,
        // и если все совпадает, присваиваем значение переменной user,
        // которая будет видна в экземпляре производного воркера.
    }
}


Теперь, когда общая для всех воркеров часть работы закодирована, мы в производных классах пишем так:

Код

@Override
public Page execute(HttpServletRequest request, HttpServletResponse response) {
    super.execute(request, response);

    // а тут уже делаем все специфическое для данного воркера
}


Из предыдущего фрагмента особенно хорошо заметно, насколько убоги штатные средства работы с куками. Например, Cookie[] request.getCookies() еще нужно не забыть проверит на null, не говоря уж о выуживании кук по имени. Поэтому, diablero, будет хорошо, если ты реализуешь удобные методы работы с куками в классе Page.

После этого у тебя не должно возникнуть затруднений, чтобы сделать в шапке избирательное приветствие: либо "Привет, diablero! | Выход", либо "Имя: | Пароль: | Войти".


Это сообщение отредактировал(а) Stampede - 26.7.2007, 01:12


--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
diablero
Дата 26.7.2007, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Цитата(Stampede @  26.7.2007,  01:02 Найти цитируемый пост)
Ну, я бы точно по другому сделал. У тебя там бины данных, менеджеры и воркеры в одной куче оказались.

А как бы ты сделал?


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
Maksym
  Дата 26.7.2007, 13:16 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 24
Всего: 62



Тем, кто, возможно, захочет пройти путем diablero:
  • Коротенькая статейка по JPА, все что нужно, чтобы начать работу и набросать простую базу  (Entitiy, One-to-One, One-to-Many, Many-to-Many Relationships): Часть 1Часть 2.
  • Руководство по Apache'вскому OpenJPA,включает в себя обзор JPA стандарта, можно подсмотреть более тонкие вещи: OpenJPA users guide
  • Пару слов про cookies в википедии
  • Все, что нужно знать про Velocity: User's guide.

PM MAIL   Вверх
Stampede
Дата 26.7.2007, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 66
Всего: 144



Цитата(diablero @  26.7.2007,  00:31 Найти цитируемый пост)
Цитата(Stampede @  26.7.2007,  01:02 Найти цитируемый пост)
Ну, я бы точно по другому сделал. У тебя там бины данных, менеджеры и воркеры в одной куче оказались.

А как бы ты сделал? 



А ты угадай smile


Цитата(Maksym @  26.7.2007,  04:16 Найти цитируемый пост)
Тем, кто, возможно, захочет пройти путем diablero:


Maksym, спасибо за ссылки.

Это сообщение отредактировал(а) Stampede - 26.7.2007, 16:17


--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
diablero
Дата 26.7.2007, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Цитата(Stampede @  26.7.2007,  16:13 Найти цитируемый пост)
А ты угадай

Думаю угадаюsmile
Мне осталось с Cookie разобраться. Завтра доделаю, а сейчас арбайтен по стахановски


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
Maksym
Дата 28.7.2007, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 24
Всего: 62



По поводу Cookies. Чтобы не писать лишнего, а сосредоточится на архитектуре, можно взять вот такой утилитный класс (спионерено отсюда):
Код

/**
 * A utility class used to cookies set by an application on the client browser.
 */
public class CookieManager 
implements Serializable {
    
    /**
     * Contains the cookies that were most recently sent in by the client's
     * most recent HTTP request.  If no cookies are present on the client,
     * clientCookies may be null.
     */
    private transient Cookie[] clientCookies = null;
    
    /**
     * Contains the Echo applications "working copy" of the cookies.  This
     * map references cookies by their names, and may contain cookies that the
     * Echo application has requested to be set but that have not yet been set
     * on the client.
     */
    private Map localCookieMap = null;

    /**
     * A set of cookies that have changed.  Cookies are stored in this set when
     * addCookie() is called, such that they will be updated in the HttpResponse
     * generated by the Connection.  Deleted cookies are also stored in this 
     * set, with there expiration set to zero, such that the client will delete
     * them.  The contents of this set are sent to the client at the next 
     * possible opportunity.
     */    
    private Set updatedCookies = new HashSet();

    /**
     * Adds a new cookie or updates an existing one.  In the case of updating an
     * existing cookie, be certain to reset its maximum age with setMaxAge() if
     * necessary.  (Cookies on the client browser do not report their maximum 
     * age to the server, only their value.)
     *
     * @param cookie The cookie to add or update.
     */
    public void add(Cookie cookie) {
        getLocalCookieMap().put(cookie.getName(), cookie);
        
        updatedCookies.add(cookie);
    }
    
    /**
     * Clears the locally held information about cookies.
     */
    private void clearLocalCookieMap() {
        localCookieMap = null;
    }
    
    /**
     * Returns a cookie with the given name if it is exists or null if it
     * does not.
     *
     * @param name The name of the cookie to return.
     * @return The cookie identified by <code>name</code>.
     */
    public Cookie get(String name) {
        return (Cookie) getLocalCookieMap().get(name);
    }

    /**
     * Creates a new local cookie set, copying the client cookies array into it.
     * This method is lazily called by other methods that need to work with the
     * local cookie map.
     *
     * @return A map containing the client's cookies.
     */
    private Map getLocalCookieMap() {
        if (localCookieMap == null) {
            localCookieMap = new TreeMap();

            if (clientCookies != null) {
                for (int index = 0; index < clientCookies.length; ++index) {
                    localCookieMap.put(clientCookies[index].getName(), clientCookies[index]);
                }
            }
        }
        
        return localCookieMap;
    }
    
    /**
     * Returns an iterator over all present cookies.
     *
     * @return An iterator over all present cookies.
     */
    public Iterator iterator() {
        return getLocalCookieMap().values().iterator();
    }
    
    /**
     * Removes the specified cookie.  This is accomplished by setting
     * the cookie on the client with a maximum age of 0.
     *
     * @param name The name of the cookie to remove.
     */
    public void remove(String name) {
        Cookie cookie = get(name);
        
        cookie.setMaxAge(0);
        
        if (localCookieMap != null) {
            localCookieMap.remove(name);
        }

        updatedCookies.add(cookie);
    }

    /**
     * Retrieves cookies from a client HTTP request and stores them in the 
     * CookieManager.  
     * When this method is called, all "working information" about cookies 
     * is destroyed.
     *
     * @param request An <code>HttpServletRequest</code> from which to 
     *        extract cookies.
     */
    void retrieveCookies(HttpServletRequest request) {
        clientCookies = request.getCookies();
        clearLocalCookieMap();
    }
    
    /** 
     * Returns the number of cookies present.  This is the number of cookies
     * that the Echo application is tracking at the current time.  Calls to the
     * add and remove methods will increase or decrease this number even though
     * the cookie has not yet been added or removed on the client.
     *
     * @return The number of cookies present.
     */
    public int size() {
        return getLocalCookieMap().size();
    }
    
    /**
     * Stores cookies on the client by adding them to the HTTP response.
     * When this method is called, all "working information" about cookies 
     * is destroyed.
     *
     * @param response An HttpServletResponse to feed the cookies to.
     */
    void storeCookies(HttpServletResponse response) {
        if (updatedCookies != null) {
            Iterator it = updatedCookies.iterator();

            while (it.hasNext()) {
                response.addCookie((Cookie) it.next());
                it.remove();
            }
        }
    }
}

PM MAIL   Вверх
diablero
Дата 28.7.2007, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Цитата(Stampede @  26.7.2007,  01:02 Найти цитируемый пост)
После этого у тебя не должно возникнуть затруднений, чтобы сделать в шапке избирательное приветствие

Всетаки возникло. Я чего-то никак не доганю как выход сделать.
Код

public class Page extends VelocityContext {
    private HttpServletRequest request;
    private HttpServletResponse response;
    private String redirectUrl;

    public static final int AGE_NINETY_DAYS = 3600 * 24 * 90;

    public Page(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        put("request", request);
        put("response", response);
        put("url", request.getRequestURI());
    }
    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }
    public String getRedirectUrl() {
        return redirectUrl;
    }
    public void setLongLivedCookie(String name, String value) {
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(AGE_NINETY_DAYS);
        response.addCookie(cookie);
    }
    public void resetCookie(String name){
        Cookie[] cookies = request.getCookies();
        if(cookies!=null) {
            int size = cookies.length;
            for(int i=0; i<size; i++){
                if(cookies[i].getName().equals(name)) {
                    cookies[i].setMaxAge(0);
                    response.addCookie(cookies[i]);
                    break;
                }
            }
        }
    }
    public String getCookieValue(String name){
        Cookie[] cookies = request.getCookies();
        if(cookies!=null) {
            int size = cookies.length;
            for(int i=0; i<size; i++) {
                if(cookies[i].getName().equals(name)) return cookies[i].getValue();
            }
        }
        return null;
    }
}

Код

public class LoginWorker extends AbstractWorker implements Worker {
    private String templateName;
    protected Page page;
    private Logger logger = Logger.getLogger(Infinite.class);
    public Page execute(HttpServletRequest request, HttpServletResponse response) {
        page = new Page(request, response);
        String url = request.getRequestURI();

        if(url.equals("/submit/login.do")) {
            logger.info("login");
            String userName = request.getParameter("userName");
            String password = request.getParameter("password");
            Infinite infinite = Infinite.getInstance();
            UserManager manager = infinite.getUserManger();
            User user;
            try {
                user = manager.login(userName, password);
                page.setLongLivedCookie("userName", user.getName());
                page.setLongLivedCookie("password", user.getPassword());
                templateName = "template.vm";
                page.setRedirectUrl("/home.shtml");
            } catch (Exception e) {
                page.put("flag", "login");
                templateName = "confirmation.vm";
            }
        }
        if(url.equals("/submit/unlogin.do")) {
            logger.info("unlogin");
            page.resetCookie("userName");
            page.resetCookie("password");
            page.setRedirectUrl("/home.shtml");
            templateName = "template.vm";
        }
        return page;
    }
    public String getTemplateName() {
        return templateName;
    }
}

Во втором if'е надо плюшки сбросить и перегрузить главную страницу. Если даже сбросить вручную, то это ничего не дает. Потому, что при редиректе на home.shtml ничего не происходит.

Код

public class HomeWorker extends AbstractWorker implements Worker {
    protected Page page;
    public Page execute(HttpServletRequest request, HttpServletResponse response) {
        super.execute(request, response);
        page = new Page(request, response);
        if(user!=null) {
            page.put("user", user);
            page.put("flag", "unlogin");
        }
        page.put("logincontent", "confirmation.vm");
        page.put("content", "home.vm");
        return page;
    }
}

Код

#if($flag=="login")
<html>
<head>
    <title>Login</title>
</head>

<body>
<center>
<br><br><br><h2>Login Page</h2><br>
Please enter your user name and password.<br><br>
#if($error==true)
<font color="#FF0000">Invalid user name or password</font><br>
#end
<form action="/submit/login.do" method="post">
<table>
    <tr>
        <td>User name: </td>
        <td><input type="Text" name="userName"></td>
    </tr>
    <tr>
        <td>Password: </td>
        <td><input type="Password" name="password"></td>
    </tr>
    <tr>
        <td align="right" colspan="2"><input type="Submit" value="Войти"></td>
    </tr>
</table>
</form>
</center>
</body>
</html>
#elseif($flag=="unlogin")
Привет, $user.name ( <a href="/submit/unlogin.do">Выход </a> )
#else
Привет, Гость ( <a href="/submit/login.do">Войти </a> )
#end


Это сообщение отредактировал(а) diablero - 29.7.2007, 15:45


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.1106 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.