Что такое сервлет и зачем нужен портлет?

    И так, дорогие друзья, я планирую открыть блог, посвящённый портальным технологиям.
    Для разогрева, предлагаю вам коротенький рассказик, прочитав которую, вы узнаете что такое сервлет и зачем изобрели портлет. Места мало, обо всем напишу кратенько. Переписывать книжки, коих выпущено не одна сотня, я не собираюсь. Я буду писать о общих вещах, а так же о приёмах, которые существенно упрощают жизнь разработчику. Если вы хотите узнать больше, то лучше http://java.sun.com/javaee/index.jsp
    вряд ли что-то может быть.
    Приготовьтесь, вы ощутите мощь Java EE.

    Интро


    Пишем мы портлеты на Джаве (Java). Что же такое портлет (portlet)? Портлет, это по своей сути -— сервлет (servlet).

    Servlet


    Это класс, расширяющий HttpServlet, у которого есть два главных метода
    void doGet(HttpServletRequest request, HttpServletResponse response){}
    void doPost(HttpServletRequest request, HttpServletResponse response){}
    Не секрет, что браузер может инициировать два вида запроса к серверу: пост (POST) и гет (GET).
    Как вы уже догадались, первый метод сработает при запросе GET к сервлету, второй — при запросе POST.
    Можно переопределить третий главный метод
    void processRequest(HttpServletRequest request, HttpServletResponse response){}
    Он будет обрабатывать и геты и посты, приходящие к сервлету.

    Параметры запроса мы вытаскиваем из request, результат записываем в response. Респонс уходит к браузеру клиента.
    Можно получить какой-то конкретный параметр, список всех имен, карту (Map).
    Map -— это интерфейс, смысл его заключается в том, что он хранит ключ и значение, связанных с ключом. В случае с параметрами запроса, ключом является имя параметра, значением -— значение параметра (железная логика).
    Например, пользователь заполнил форму регистрации и отправил её на сервер:
    lolik.ru/registrationservlet?name=lolos&surname=lolobot&age=102
    Карта параметров будет выглядеть следующим образом:
    name->lols
    age->102
    surname->lolobot

    Если интересно, о картах и прочих вкусностях Java SE мы можем поговорить отдельно.
    Значениями параметров реквеста могут быть только строки (String), которые можно привести к нужному типу. Очевидно, значение age лучше превратить в целое число (int или Integer).

    Посмотрим на метод:
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
    out.println("");
    out.println("");
    out.println("Servlet MyServlet");
    out.println("");
    out.println("");
    out.println("

    Servlet MyServlet at " + request.getContextPath () + "

    ");
    out.println("
    lols!
    ");
    out.println("");
    out.println("");
    } finally {
    out.close();
    }
    }

    Берём респонс, пихаем в него html и отправляем пользователю.

    Ремарка:
    Спасибо zer0access за то, что поправил меня. Пройдя по ссылке java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpServlet.html вы увидите, что есть ещё методы, кроме doGet и doPost.
    Метод processRequest генерируется рядом IDE, например NetBeans 6.1 Делается это следующим образом:
    /**
    * Handles the HTTP GET
    method.
    * param request servlet request
    * param response servlet response
    */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    /**
    * Handles the HTTP POST method.
    * param request servlet request
    * param response servlet response
    */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    т.е. описав метод processRequest, ваши doPost и doGet отработают единообразно. Если есть разница при вызове doPost или doGet, то использовать processRequest врядли придётся.
    Метод service первым принимает запрос, после запрос переправляется нужному doXxx. В service можно сделать какие-то общие операции, например сделать запись в БД, что такой-то пользователь обратился к такому-то сервлету, затем запрос передается на обработку нужному методу сервлета.
    zer0access, спасибо тебе.

    Всем сервлеты хороши, но только один сервлет может быть на странице. Два сервлета не влезут — слишком важные персоны.
    Как же быть, если очень хочется на одну страницу поместить сервлет-калькулятор и сервлет-переводчик?

    Portlet


    Очень просто — написать два портлета, один будет считать, второй — переводить. Два, три, много портлетов можно поселить на одной странице. Классический портлет в редакции Sun имеет три режима: view, edit, help. Первый — основной, его видит пользователь. В случае калькулятора, в режиме view (просмотр) будут доступны кнопки. В режиме edit (настройки), например, можно задавать тип калькулятора: обычный или научный, с синусами, косинусами и прочими мудрёными вещами. В режиме help (справка)? как вы уже догадались, будет справка по калькулятору.
    Режимы view, edit, help отображаются при помощи jsp (java server pages). Они очень-очень похожи на php-страницы:

    <% for(int i=1; i<=10; i++){ %>
    <%=i%>
    <br>
    <%}%>


    Вывод в столбик чисел от 1 до 10 включительно.

    можно заменить <%%> на <_? ?_> (как тут пхпшный код-то писать?) и разницы не будет (за исключением того, что Джава требует определения типов переменных).
    С режимом view и help все понятно, а зачем нужен режим edit? Допустим, У нас на портале есть две группы пользователей: первая — бухгалтеры, вторая — мы с вами, программисты. Бухгалтерам достаточно обычного калькулятора, где есть +,-,*,/, а нам нужно складывать двоичные числа. В этом случае администратор портала для группы бухгалтеров настроит портлет, как обычный калькулятор, а для нашей группы, как научный.

    Чувствуете какой кайф?
    Портлет, считай, как маленькое веб-приложение, которое можно поместить на страничку портала и настроить (если возможность реализована программистом) под конкретные нужды пользователя. Можно комбинировать разные портлеты на одной странице.

    В следующем номере мы поговорим о портлетах более подробно. Я расскажу, как можно за 5 минут настроить сервер приложений, контейнер для портлетов и как отлаживаться на всем этом хозяйстве нажатием одной кнопки.

    Комментарии 29

      0
      плюсанул в карму. перенести в блог j2ee не помешало бы
        0
        Спасибо! В J2EE? Подскажи, пожалуйста, как его найти. Поиск почему-то не находит блог. Я ещё не до конца въехал в хабратему
      0
      а какой портлетный сервер ты планируешь использовать для повествования?
        0
        В начале я расскажу про GlassFish + OpenPortlet Container. Думаю, что версию 1.0 (под JSR168) я трогать не буду, ибо скоро про неё забудут. Я буду писать про версию 2.0, т.е. JSR286 и IPC (interportlet communication = обмен сообщениями) этой спецификации. Я вскоре займусь экспертизой Sun'овского портала, напишу про Sun Java System Portal Server 7.x. Там есть очень крутая тема - AJAXTableContainer, позволяющая портлетам грузиться и обновляться без перезагрузки страницы. Такая же фича есть у IBM, но их порталы стоят таких денег (до 100000 $), что про них писать нет смысла. Сановский портал, ГлассФиш, ОпенПортлет контейнер можно использовать и не платить, а с IBM такая фишка не прокатит.
        +3
        Не согласен насчёт сервлетов. С каких пор processRequest стал главным методом? То, что данный метод генерируется несколькими IDE вовсе не означает, что именно данный метод надо реализовывать. Если посмотреть на интерфейс HttpServlet (http://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpServlet.html), то можно заметить, что метода processRequest там нет. Общим методом при получении запроса является service(HttpServletRequest req, HttpServletResponse res), который вызывается при получении запроса от клиента. И только затем вызывается нужный метод doXxx, которых насчитывается 7, хотя в основном используются doGet и doPost.
        Фразы о том, что 2 сервлета не влезают на одну страницу, звучат по меньшей мере странно. Сервлет - это не страница и говорить о каких-либо сервлетах на странице нельзя. С помощью форвардинга и перенаправления запросов можно выдать пользователю и калькулятор, и переводчик на одной странице. Просто 2 разных сервлета будут работать с одним и тем же объектом HttpServletResponse.
        Итого, статья не совсем грамотная.
          0
          Насчет processRequest, я не прав. Спасибо за комментарий. Сейчас поправлю статью.
          Теперь про страницу. Согласен, сервлет, это не страница. Я имел ввиду другое, посмотрите, пожалуйста, картинку: http://www.rippe.com/pictures/samplewebs…
          Справа внизу находится портлет "My Weather", помимо него на странице портала размещены ещё два портлета. при помощи инструментов администрирования можно с лёгкостью убрать со страницы "My Weather", на работе двух других портлетов это никак не скажется. Не надо использовать форвардинг и перенаправление запросов, достаточно написать портлет, поместив его в веб-приложение. После развёртывания веб-приложения на сервере, можно использовать портлеты, как мини-приложения, перемещая их по страницам.
          Хочу заметить, что портлет в редакции IBM - это наследник HttpServlet, а в редакции Sun - это отдельный класс, GenericPortlet.
          В следующей заметке я буду использовать скриншоты, тогда мои мысли будет легче воспринимать читателям. Понятно излагать свои мысли, важное умение, буду учиться.
            0
            Да, я понял пример с портлетами. Просто мне не доводилось их использовать, но смысл в целом ясен. Фактически, сервлеты и портлеты имеют различное предназначение. Если сервлеты в основном используются для логики приложения, то портлеты - это независимые фрагменты пользовательского интерфейса с возможностью их интеграции (http://en.wikipedia.org/wiki/Portlet).
            В принципе, их сравнение не совсем корректно из-за различного предназначения. Хотя описание в заметке нормальное.
              +1
              В контексте Sun, да, это разные вещи. У IBM портлет - это наследник сервлета. Концепция IBM мне нравится больше, но уж слишком все дорого у них. За такие бабки можно и по-лучше делать сервера.
          +1
          "Чувствуете какой кайф? Портлет, считай, как маленькое веб-приложение, которое можно поместить на страничку портала и настроить"

          Не вводите людей в заблуждение надуманным примером с калькулятором, пожалуйста — вместо слова "кайф" должно быть "геморрой". Портлетная технология создаёт множество проблем и ни одной (кроме _одноразовой_ настройки структуры страницы) не решает (или решает в стиле "сферического коня", налагая дополнительные ограничения).
            +1
            Я не очень вас понял. Если вас не затруднит, поясните, что имеете ввиду.
            Проблемы, с которыми я лично сталкивался, были связаны с конкретными глюками портального сервера (особенно в IBM WebSpshere Portal Server 5.0).
            Пример с калькулятором не надуманный. Посмотрите, пожалуйста, https://portlet-repository.dev.java.net/ - это репозиторий портлетов JSR-168. Идея хорошая, но, к сожалению, JSR-168 неконкурентоспособный по сравнению, например, с портлетами спецификации IBM. С выходом IPC для JSR-168 открылись новые возможности для разработчиков.
            JSR-286 обещает быть хорошим и плюшевым.
              +1
              Основная проблема портлетной технологии в том, что она рассматривает страницу как набор _независимых_ блоков, что, как правило, не так. Если есть список — где-то на странице есть фильтр(ы). Если есть просмотр — где-то наверняка есть комментирование (кругом web 2.0, UGC). Да, в 286 сделали обмен сообщениями — но это всё равно механизм для взаимодействия слабосвязанных объектов, да ещё и порождается по итогам ActionRequest. Представьте себе, что на странице есть список документов и пара фильтров. Как при простом заходе на страницу Вы сможете отфильтровать список какими-то дефолтным способом?

              По сути дела, страница из портлетов подобна набору фреймов — со всеми проблемами фреймовой структуры. Отдать пользователю постоянную ссылку на страницу практически невозможно — параметры либо легли в сессию/RenderRequest после предыдущего post-запроса и редиректа, либо url страшен, как смертный грех. Один из вопросов, который кочевал от заказчика к заказчику — "нельзя ли сделать url попроще?"

              По поводу моих слов о надуманности примера с калькулятором и репозиторим портлетов. Скажите, Вы действительно считаете, что на сайте необходим блок с погодой, JNDI-браузер или непонятная замена браузерных букмарков/любого сервиса букмарков? Вас не настораживал тот факт, что мысль сторонних разработчиков не пошла дальше этих игрушечных компонент? Никто почему-то не написал форум, который мистическим образом интегрируется с моими пользователями и классификаторами. Никто почему-то не написал облако тегов, которое интегрируется с моими типами объектов в моей БД. Никто даже не написал простейшего списка, который показывал бы объекты в соответствии с системой прав и состояниями docflow/workflow/someshitflow. Репозитории 3rd-party портлетов — это миф, наполненный калькуляторами и интеграцией с Flicrk'ами.
                +1
                IPC есть и в JSR-168. К сожалению, появился он поздно. Я не понял фразу про "механизм для взаимодействия слабосвязанных объектов" - в IPC есть эмиттер, есть ресивер (портлет, отправляющий сообщение, портлет, принимающий сообщение), что особым образом прописывается. Я бы не сказал, что это слабосвязанные объекты. Насчет ссылки - да, это косяк, причём сильный.
                Насчет надуманности. К сожалению, я не могу писать о том, чем занимаюсь, но "ненадуманный" пример приведу.
                Есть портлет, который ищет сотрудников в БД. Кстати, в настройках портлета можно задать к какой именно БД он лазиет. Рядом с ним лежит портлет, отображающий инфу по сотруднику: ФИО, должность, подразделение, ЗП и т.д. Он получает сообщение от поискового портлета. В настройках инфо-портлета мы можем указать количество полей для отображения, возможность их редактирования. Третий портлет - выводит то, в каких проектах задействован выбранный сотрудник.
                Для обычных пользователей достаточно первого, поискового портлета, выводящего ФИО+тел сотрудника. Для HR'a пригодится второй. Для ПМ понадобится третий. На портале у нас есть группа анонимных пользователей, которые видят поисковый портлет, есть группа HR, где есть подгруппы с разными правами на доступ ко второму портлету:кому-то достаточно просмотра инфы о сотруднике, а кто-то может изменять данные. ПМ'ы используют поисковый портлет и проектный портлет. Плохой пример?
                  0
                  Пример непонятен. Вы эти портлеты взяли из какого-то репозитория?

                  "Можно задать, к какой именно БД" — вплоть до структуры? Вы можете сказать, что в этом проекте портлет должен доставать данные из таблицы users, а в этом — из logins плюс сходить в LDAP? Или всё из того же users, но данные хранятся в CLOB-поле в виде vcard-xml. Сомневаюсь. В том-то и проблема, что невозможно разработать универсальный портлет и положить его в репозиторий всем на радость (или же вокруг него придётся дописывать своего кода больше, чем если делать свой собственный портлет). Потому я и говорю, что репозитории портлетов — миф.

                  Возвращаясь к примеру — в данном случае сложно рассуждать о полезности портлетов, не имея данных об их повторном использовании на других страницах. Пока видно только ограничение видимости отдельных частей одной страницы, что можно было бы настроить и как-нибудь ещё.

                  Кстати, какой из портлетов здесь отвечает за формирование title и keywords страницы?
                    0
                    Блин, что за косяк с сессией? постоянно отключаюсь.
                    Насчёт репозиторий портлетов=миф, я, пожалуй, соглашусь с вами, хотя портлеты для общих задач писать можно.
                    Какая БД - которую создал администратор БД. Я говорю о живом, реальном проекте. Посмотрите на любой интранетовский корпоративный портал, описанный функционал есть практически в каждом из них. Ограничение видимости и то, что я описал - разные вещи.
                    Тайтл страницы и кейворды пишет админ портала. Он же размещает портлеты на страницах. Он же управляет группами пользователей, в идеале, он еще и настроит под них портлеты.
                    По всей видимости, я плохо излагаю свою мысль. Давайте поступим так, сегодня-завтра я напишу, как настроить среду для разработки и отладки портлетов, а в следующем топике приведу хороший пример, постараюсь показать преимущества портлетов.
                    У портлетов есть свои недостатки, и их не мало, я не спорю с этим. У меня другая цель.
            +1
            тема портлетов, увы, ни разу не раскрыта :(
              0
              ..а что такое сервлет знает каждый J2EE developer. В сухом остатке пользы от статьи маловато, но всё равно жду продолжения.
                +1
                Спасибо за комментарии, я их учту в следующем опусе. Я попытался связать сервлет и портлет, чтобы объяснить полезность и актуальность второго. Далее, буду раскрывать тему.
                  +1
                  да, +1
                  хотя портлеты вроде как не слишком популярны нынче
                    0
                    http://www.javaportal.ru/java/articles/p…
                    секция Понятие портлетов
                    "Портлеты - новая "горячая" технология разработки Web-приложений."
                    а теперь нажмен кнопочку Home и увидим дату создания статьи: 2003 год =(
                    но всё равно хорошо, что java не бедна фреймворками/библиотеками/идеями.
                0
                Почитал заметку. Замечательно, что появляются статьи посвящённые технологиям Java. Посему автору большой плюс. А теперь по сути статьи.

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

                Теперь, что касается портлетов. Технология не так уж и нова и придумывалась для того, что бы облегчить создание порталов. Откуда собственно и название. И вот тут, видимо, нужно о-очень явно оттенить, что же такое есть портал. К сожалению, как мне кажется, это слово уже давно имеет два смысла.

                Первый смысл – бытовой. В этом смысле портал есть просто любой крупный тематический сайт, который постоянно (оперативно) обновляет свою информацию. Любой сайт, с более менее разношерстной информацией часто называют порталом. Городской портал, школьный портал.

                А вот второй смысл – уже более технический. В этом смысле, порталом называется сайт, страницы которого, преимущественно, состоят из набора логически не связанных между собой кусочков. Логически не связанных! Вот это надо прибить гвоздями и уж затем, рассматривать плюсы или минусы данной технологии. Есть действительно сайты, в которых информация стуктурирована таким вот образом. В одном углу блок погоды, в другом биржевые новости, в третьем програма телепердач, а в четвёртом результаты скачек. Все эти кусочки никак не связаны между собой. Вот для того, что бы логически разделить создание этих кусков и придуманы портлеты.

                И вот эти независимые портлеты не нужно путать с просто кусками сайта, которые очерчены лишь визуально. К примеру, строка поиска, является визуально очерченной компонентой, но не логически независимой. Ну потому, что она должна вывести результат в другую часть страницы. Которая, стало быть, от неё зависима.

                Вот в контексте этого, становится понятно, почему нельзя “упрекать” портлеты в невозможности держать контроль над всей страницей или в том, что они плохо взаимодействуют между собой.
                Если у вас части страниц сайта логически зависимы, вам просто не нужно использовать портлеты. Мы, к примеру, используем Wicket. Фреймворк, который даёт очень хороший и элегантный контроль над страницей, позволяя при этом иметь большое количество повторно используемых визуальных панелей. Которые в свою очередь опираются на бизнес классы аккуратно поддерживаемые Spring.
                  0
                  Спасибо,посмотреть профиль Steamus, я понял свои ошибки, буду их постепенно исправлять.
                  0
                  Можно привести какие то параллели с технологией JavaServer Faces (JSR 127, JSR 252 и JSR 314)?

                  Можете написать, какие эволюционные изменения произошли на пути от JSP/Servlets к JSF и как это повлияло на портлеты?
                    0
                    С JSF я ни разу не сталкивался, к сожалению, я не могу ответить на ваш вопрос.
                    Слышать-слышал, но что это и как это-понятия не имею.
                    http://java.sun.com/j2ee/1.4/docs/tutori…
                    Глава 17, Chapter 17: JavaServer Faces Technology

                    Если будут единомышленники, можно поковырять эту штуку, пописать переводики и простенкие примерчики. В рунете что-то толковое по J2EE, даже по J2SE найти сложно.
                  0
                  Использоватл портлеты около 1.5 года (Weblogic). Межпортлетное взоимодействие там довольно сложно организовать, но вполне возможно (контекстная помощь в веб-приложении, например).
                  По-моему, проще использовать банальные tiles, мощь портлетов чаще всего не нужна.
                  Хотя, собственно, могу и ошибиться...

                  Спасибо за пиар Java :)
                    +1
                    За что я люблю Java - так это за простоту языка, удобство разработки и за бабло которое мне за нее платят. Отличная технология. Отличный пост.
                    • НЛО прилетело и опубликовало эту надпись здесь

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

                      Самое читаемое