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

Поиск:

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


Опытный
**


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

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



Цитата(Stampede @  16.7.2007,  18:16 Найти цитируемый пост)
Значит, ЧПУ* не хочешь?

Можно и ЧПУ, я за то как нам удобней.
На мой взгляд по id проще запросы будут. Хоть это и относительная простота, но все же.

Это сообщение отредактировал(а) diablero - 16.7.2007, 19:23


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


Гносеолог
**


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

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



Цитата(diablero @  16.7.2007,  10:20 Найти цитируемый пост)
На мой взгляд по id проще запросы будут.


Хорошо, договорились. Итак, предлагай УРЛы для следующих страниц: раздел, статья и профиль. Я со своей стороны предлагаю использовать имя в формате [имя.расширение], причем расширение - не типичное для сервлетных книжек .do, а такое, которое указывало бы на характер ссылаемого документа. Например, я считаю, что .shtml было бы вполне уместно - так традиционно помечают динамические странички, генерируемые с использованием технологии SSI (Server-Side Include). Но в принципе выбор твой.



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


Опытный
**


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

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



Цитата(Stampede @  16.7.2007,  19:39 Найти цитируемый пост)
Например, я считаю, что .shtml было бы вполне уместно - так традиционно помечают динамические странички, генерируемые с использованием технологии SSI (Server-Side Include).

Я согласен. 

news.shtml
section.shtml
article.shtml
account.shtml

Это сообщение отредактировал(а) diablero - 16.7.2007, 19:56


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


Гносеолог
**


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

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



Отлично.

Итак, приступаем к вебу. Для начала нам нужно прикрутить к проекту шаблонный движок. Особой разницы между ними нет, так что возьмем хорошо всем знакомый Velocity, легкий и шустрый.

Надо будет написать класс TemplateManager такого примерно содержания:

Код

public class TemplateManager implements Manager {
    private VelocityEngine engine;

    public void init() {
        // создаем инстанс движка и инициализируем его пропертями из conf/velocity.properties
    }

    public String merge(String templateName, Context context) {
        // через движок получаем объект Template, сливаем с контекстом, выдаем строку
    }

    public void destroy() {
        // чего-нибудь высвобождаем/закрываем
    }
}


Как мы видим, в таком виде менеджер шаблонов получается у нас практически независимым от Velocity, то есть при желании его можно будет переделать под любую технологию рендеринга, включая XSLT и JSP. Опять же, можно запросто оформить это дело как интерфейс, а для Velocity написать реализацию VelocityTemplateManager. Но я напоминаю, мы не делаем библиотеку общего назначения, мы делаем просто сайт. Подчеркиваю это специально для niasilil, который, похоже, несколько излишне загрузился вопросом:

Цитата(niasilil @  15.7.2007,  21:30 Найти цитируемый пост)
Удивительно. А как же принцип "program to an interface"? 


niasilil, я там отписался в твоей теме.

Шаблоны предлагаю хранить в отдельной папке {home_dir}/template.



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


Опытный
**


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

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



Цитата(Stampede @  16.7.2007,  20:26 Найти цитируемый пост)
 Особой разницы между ними нет, так что возьмем хорошо всем знакомый Velocity, легкий и шустрый.

Я всеми руками за него.



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


Опытный
**


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

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



Код

public class TemplateManager implements EngineManager{
    private VelocityEngine engine;
    private Logger logger = Logger.getLogger(Infinite.class);

    public void init() {
        Infinite infinite = Infinite.getInstance();
        String homeDir = infinite.getHomeDir();
        try {
            engine = new VelocityEngine(homeDir+"/conf/velocity.properties");
        } catch (Exception e) {
            logger.error(e);
        }
    }

    public String merge(String templateName, Context context) {

        return null;
    }

    public void destroy() {
        engine = null;
    }
}

Цитата

через движок получаем объект Template, сливаем с контекстом, выдаем строку

А строку мы из Writer'а получаем?


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


Гносеолог
**


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

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



Цитата(diablero @  16.7.2007,  13:41 Найти цитируемый пост)
А строку мы из Writer'а получаем? 


Используй StringWriter.

 >  private Logger logger = Logger.getLogger(Infinite.class);

Вообще-то идея была в каждом классе заводить логгер, используя свой собственный класс (сорри за тавтологию). То есть передавать TemplateManager.class.

Далее: обработка исключений. Везде, где встречаем библиотеко-зависимые чекнутые исключения - ловим, заворачиваем в рантаймное и пробрасываем дальше. А не глотаем, как у тебя.

Хорошо было бы еще на содержимое velocity.properties посмотреть.

Ну и тест какой-нить прогони и расскажи как получается.


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


Опытный
**


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

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



Пока так.
Код

input.encoding = UTF-8
output.encoding = UTF-8
file.resource.loader.path = templates



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


Гносеолог
**


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

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



> file.resource.loader.path = templates

Тут есть одна тонкость. Это у тебя работает до тех пор, пока ты запускаешь тест из корня проекта (который у тебя совпадает с домашней директорией). При запуске из контейнера это сломается. К сожалени, Velocity не понимает переменные окружения. Один из выходов заключается в том, чтобы вручную загрузить проперти, получить значение file.resource.loader.path, подменить в нем переменную домашней директории (по шаблону) реальным значением, и засунуть обратно в проперти. Потом инициализировать движок методом VelocityEngine.init(Properties props).

То есть в конфиге будет примерно такое:

file.resource.loader.path = {home_dir}/templates

Так как там с тестом?


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


Опытный
**


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

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



Готово.
Код

public class TemplateManager implements EngineManager{
    private VelocityEngine engine;

    public void init() {
        Infinite infinite = Infinite.getInstance();
        String homeDir = infinite.getHomeDir();
        try {
            String tml = "{home_dir}";
            Properties properties = new Properties();
            properties.load(new FileInputStream(homeDir+"/conf/velocity.properties"));
            String value = properties.getProperty("file.resource.loader.path");
            value = value.substring(tml.length(), value.length());
            properties.put("file.resource.loader.path", homeDir+value);
            engine = new VelocityEngine(properties);
        } catch (Exception err) {
            throw new RuntimeException(err);
        }
    }
    public String merge(String templateName, Context context) {
        try {
            StringWriter sw = new StringWriter();
            engine.mergeTemplate(templateName, context, sw);
            return sw.getBuffer().toString();
        } catch (Exception err) {
            throw new RuntimeException(err);
        }
    }

    public void destroy() {
        engine = null;
    }
}

test.shtml
Код

<html>
<head>
<title>$article_title</title>
</head>
<body>
<div class="user">    
  User name: $user.getName()    
</div>

</body>
</html>

Код

public class UserDataTest extends DataTest{
    protected void doTest() {
        Infinite infinite = Infinite.getInstance();
        UserManager manager = infinite.getUserManger();

        try {
            //manager.login("bobr", "54321");

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        User user = manager.getUser(105);
        TemplateManager templateManager = infinite.getTemplateManager();

        Context context = new VelocityContext();
        context.put("article_title", "ПРЕВЕД");
        context.put("user", user);
        templateManager.merge("test.shtml", context);
    }
}


Это сообщение отредактировал(а) diablero - 17.7.2007, 00:38


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


Гносеолог
**


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

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



Ништяк! smile

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

Нам щас нужно сделать одну важную вешь: запустить все это дело из-под контейнера. Для этого придется реорганизовать структуру директорий. Все, что у тебя в корне (кроме сырцов), нужно поместить в ROOT/WEB-INF. Убедись, что скомпилированные классы лежат в WEB-INF/classes, а либы - в WEB-INF/lib. Если нужно, настрой проект как веб-приложение.

После этого пропиши в server.xml:

Код

    <Host name="localhost" appBase="c:/infinite">
        <Context path="" reloadable="true" docBase="ROOT" />
    </Host>


Можешь для удобства добавить в etc/hosts запись:

127.0.0.1       infinite

А если еще сменишь порт томката с 8080 на стандартный 80, то вообще сможешь ходить по адресу http://infinite/

Изобрази какой-нибудь web.xml по аналогии с примерами, чтоб *.jsp мапилось на JspServlet. Положи в ROOT простенькую JSPшку и попробуй вызвать ее из браузера.

Саму прогу пока не дергай.


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


Опытный
**


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

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



Все сделал. Запускаю и работает простой сервлет.

P.S. ушел спать...

Это сообщение отредактировал(а) diablero - 17.7.2007, 02:00


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


Гносеолог
**


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

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



Так, продолжаем.

Начнем потихоньку слздавать наш класс-контроллер, букву C в MVC (хотя, если кто помнит, термин  CLMV представляется мне гораздо более адекватным). Пускай он наследует от HttpServlet и дополнительно реализует ServletContextListener. Можно, конечно, сделать это и в разных классах, но в одном будет компактнее.

Update: Внимание! Как по ходу выяснилось, из-за того что листенер и сервлет имеют свой собственный жизненный цикл, объединить их в одном классе не получается. То есть делаем отдельно класс-листенер, отдельно класс-сервлет.

По contextInitialized() надо поднять Infinite. Для этого надо знать путь к домашней директории. Получаем так: ServletContext.getRealPath("/WEB-INF");

В обработке запроса, метод service(), можно для начала проанализировать УРЛ запрашиваемого ресурса, и если он соответствует одному из (раздел, статья, аккаунт), то выдать содержимое соответствующего шаблона.

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

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

Да, маппинг к сервлету-контроллеру в web.xml, естественно, удобнее всего прописать по расширению .shtml



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


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


Опытный
**


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

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



При инициализации класса Infinite вываливается эксепшен. Никак home dir получить не могу, все время он null.
В чем может быть ошибка?
Код

public class MainController extends HttpServlet implements ServletContextListener {
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        String homeDir = servletContextEvent.getServletContext().getRealPath("/WEB-INF");
        Infinite infinite = Infinite.getInstance();
        infinite.init(servletContext.getRealPath(homeDir));
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
            throws IOException, ServletException {

    }
}


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


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


Опытный
**


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

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



Пролопатил пол инета. У многих проблема с getRealPath().
Пока есть только такое решение:
Код

ServletContext sc = request.getSession().getServletContext();
String str= sc.getRealPath("/");


Это сообщение отредактировал(а) diablero - 19.7.2007, 19:09


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

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

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


 




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


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

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