Познаём Java. Четвёртая чашка: сервлеты и мидлеты
Надеюсь, глянув на J2SE вы поняли как всё серьёзно, и как просто захватить весь компьютерный мир, изучив лишь один язык. Давайте теперь рассмотрим особенности двух других реализаций этого языка: J2EE и J2ME.
Преамбула, которую
Сейчас я рассмотрю особенности разработки для серверов и для мобильных телефонов. Здесь не будет примеров — их вы вполне сможете добыть в указанных местах. К сожалению, данный пост сильно запоздал после предыдущих. Это объясняется пересдачей экзамена по матану, днём рожденья и небольшим авральчиком на работе, связанным с правкой багов в новом сервисе для wap.megafonpro.ru. В итоге всё закончилось хорошо и у меня появилось свободное время. Этот пост будет, вероятно, последним, в котором рассматриваются теоретические особенности разработки. Дальше будет 2-3 поста практики: коллекции, потоки, enum'ы, аннотации и прочие радости, а потом уж посмотрим :)
P.S. Если встретили незнакомое название — гуглите по нему или смотрите в забугорной википедии. Полные описания найти не проблема.
Приложения для J2EE и J2ME имеют нечто схожее (хотя это скорее наблюдение, чем свод требований):
— часто сильно зависят от сторонних библиотек;
— обычно распространяются в архивах (war, jar);
— в их структуре выделяют конфигурационную часть и, собственно, java-классы.
Java Enterprise — звучит сильно, а? Но мы не можем сказать, что J2EE это очень мощный инструмент и всё такое прочее. Почему? Потому, что J2EE — это целая туча инструментов, спецификаций, API, и прочих радостей современной жизни.
Давайте посмотрим на основные разделы J2EE и программные продукты, которые их реализуют (внимания, слова Java и API в названиях опущены):
Итак, думаю вы получили представление о наборе стандартных средств. Кроме них, стоит упоминуть добрую сотню веб-морд (JSF, Tapestry5, Struts и прочее), которые с разными извращениями предлагают вам реализовать веб-интерфейс, предлагая всяческие вкусности и автоматизацию в обмен навашу душу требования притирки к архитектуре.
Структура простого J2EE-приложения выглядит так:
Контейнер — некое приложение, например Apache Tomcat или Jetty. Оно служит для реализации веб-доступа к вашему приложению и отвечает за приём и распределение согласно конфигурации запросов, хранение сессий и за доступ к статичному контенту. Фильтры и сервлеты описываете вы, реализуя в них нужную вам логику. Помните, они должны уметь себя проинициализировать и похоронить. Кроме того, каждый фильтр при получении запроса должен либо пустить его дальше по цепочке фильтров (таким образом запрос «падает» до сервлета), обработать его самостоятельно или же отправить на другой сервлет, по другому адресу, для обработки. Сам же сервлет так же может перенаправить запрос, или же ответить на него.
Основные понятия в работе с сервлетами — запрос и ответ, request и response. По факту, они попадают к вам извне, ваша цель — написать тело ответа.
Теоретически, этого достаточно. В клинических случаях некоторые могут обойтись одними JSP и не использовать Сервлеты/Фильтры — подключаться к БД, доставать инфу и обрабатывать ошибки прямо в JSP. Но это — не правильно.
Да и просто реализовать Сервлет — не самая лучшая идея. Вам придётся самостоятельно доставать GET/POST-параметры из тела запроса и правильно сформировать заголовки ответа. Чтобы не заниматься вознёй есть специальный HttpServlet. Он сделает всё это за вас — вам остаётся только добавить заголовков и сформировать тело ответа и переопределить методы doGet/doPost, которые по умолчанию отдают сообщение об ошибке. Собственно, на формировании тела запроса вы и должны сконцентрироваться.
Таким образом, ваши задачи:
Что ж, надеюсь в этом месте вы уже поняли основной принцип работы J2EE-приложений. Однако, набор сервлетов и фильтров нужно ещё и как-то подставить сервлет-контейнеру.
Для распространения веб-приложений также служат зип-архивы, но на этот раз с расширением .war (web archive).
Структура у них такая:
Готовый war вы подкидываете в магическую папку (обычно webapps) вашего контейнера и перезапускаете его. Контейнер его распаковывает и вешает его содержимое на IP.в.настройках.контейнера: порт/имя_war'а/.
Весь контент из корня архива станет виден по соответствующему адресу.
Если заинтересовало — качайте Tomcat/Jetty — в их поставке есть набор примеров, на которых вы сможете потренироваться.
И ещё есть хороший туториал с простыми примерами. Рекомендуется хотя бы «чисто поглядеть».
Казалось бы, мир J2ME не должен быть так же велик, как J2EE, правда? Вроде бы это не целая гора спецификаций да и цели другие… Однако, это не так. Здесь всё то же самое, но повязано на другом принципе: вы не можете выбрать набор библиотек, он определён телефоном. Здесь всё несколько интереснее.
Кроме обрезанного ядра Java (кроме всего прочего нету Java Collections Framework и в некоторых реализациях нет нецелых чисел), вы получаете набор реализованных API, так называемых JSR. Каждый имеет свой номер. По сути это небольшая библиотека, которая даёт телефону некоторый функционал. Например 82 отвечает за доступ к блютус из Java, 205 — даёт вам MMS и так далее. На самом деле большинство из них не относится к J2ME, например мы можем найти там даже спецификацию сервлетов, однако именно с J2ME выяснение набора поддерживаемых JSR становится необходимым.
Про все JSR-ки можно почитать на жутко официальном сайте.
Каждая J2ME-платформа состоит из двух основных компонент: профиля и конфигурации.
Конфигурации описывают API, реализующий внутрепрограммные операции, а профили — взаимодействие.
Конфигурации на телефонах используются две: CDC, CLDC. Они реализуют работу с потоками ввода-вывода, математическими функциями, исключениями и т.д. CLDC — более ограничена, в первой версии отсутствуют числа с плавающей точкой, слабые ссылки. В версии 1.1 (самой распространённой) эти возможности есть, но отсутствует сериализация и часть механизма Reflection.
Из профилей, для разработки MIDlet'ов используются MIDP — Mobile Information Device Profile. В него изначально входят классы для отображения мидлетов, GUI, а также систему хранения пользовательской информации RMS. В новых версиях (сейчас распространена 2.0 и в разработке находится версия 3.0) включена поддержка специфических для игр возможностей, а также поддержка мультимедиа. Кроме того, на многих телефонах реализована работа с файлами в хранилище телефона, а также API для сетевых взаимодействий — SMS, MMS, Bluetooth.
Структура программы J2ME напоминает J2SE: вы наследуете Главный Класс от MIDlet и пользуетесь магией вида
Таким образом вы подсовываете телефону некоторые экраны (Displayable, а обычно — GameScreen, у него удобнее всего ловить нажатия клавиш), за перерисовку которых отвечаете самоятоятельно. Вы можете рисовать картинки, текст, прямоугольники и ещё несколько геометрических фигур. Кстати, хорошая новость — J2ME абсолютно адекватно рисует полупрозрачные PNG.
Отдельная песня — отлов нажатий на кнопки. Реализация примитивная — на вход вы получаете число, соответствующее коду некой кнопки. В принципе, опытным путём (или из документации) они подбираются достаточно быстро, но здесь бывает подлянка: на некоторых телефонах коды кнопок могут отличаться. Этим грешат моторолы и LG.
К сожалению, боюсь я не смогу раскрыть всех прелестей программирования для мобилок. На самом деле это совершенно отдельный жанр. Работая с телефоном вы всегда должны заботиться о том, чтобы вашей программе было негде повиснуть и чтобы она не жрала память, которой может быть всего мегабайт-два. Кроме того, вы должны адекватно обрабатывать случаи, когда телефон пользователя имеет специфическое разрешение или не поддерживает нужный вам JSR. Да, ещё: для старых телефонов размер jar'а с приложением не должен превышать 300кб.
Конфигурировать своё приложение вы должны в файле MANIFEST.MF в папке META-INF jar'а. Кроме того, полезно указать те же сведения о приложении в .jad файле — на некоторых телефонах это немного ускоряет загрузку. Формат есть в википедии,
Для отладки таких приложений используется Sun Wireless Toolkit. Если некий производитель телефонов хочет выпустить эмулятор своего нового телефона, он берёт WTK, вешает на него свой скин и реализованные JSR-ки. Эмулятор готов.
К счастью, подцепить IDE к отладчику проблем не составляет, однако отлаженное в «тепличных условиях» приложение не всегда будет работать идеально на всех телефонах, поэтому на реальных моделях тоже стоит потестировать.
Пример отладки (извиняюсь за хреновое качество), но это был первый найденный скриншот из тех, что я не удалил.
А примерно вот так выглядит отладка на телефонах. На столе их 5 штук, не считая собственного :)
Что вы должны уметь для работы с J2ME:
P.S. Если надумаете эксперементировать — гуглите по java tutorial j2me/j2ee — найдёте кучу примеров. В качестве IDE рекомендую триал IntelliJ IDEA, но подойдут и Eclipse/NetBeans.
Удачи вам, уважаемые читатели. Задавайте вопросы.
Преамбула, которую лучше можно не читать
Сейчас я рассмотрю особенности разработки для серверов и для мобильных телефонов. Здесь не будет примеров — их вы вполне сможете добыть в указанных местах. К сожалению, данный пост сильно запоздал после предыдущих. Это объясняется пересдачей экзамена по матану, днём рожденья и небольшим авральчиком на работе, связанным с правкой багов в новом сервисе для wap.megafonpro.ru. В итоге всё закончилось хорошо и у меня появилось свободное время. Этот пост будет, вероятно, последним, в котором рассматриваются теоретические особенности разработки. Дальше будет 2-3 поста практики: коллекции, потоки, enum'ы, аннотации и прочие радости, а потом уж посмотрим :)
P.S. Если встретили незнакомое название — гуглите по нему или смотрите в забугорной википедии. Полные описания найти не проблема.
Что общего у серверов и мобилок?
Приложения для J2EE и J2ME имеют нечто схожее (хотя это скорее наблюдение, чем свод требований):
— часто сильно зависят от сторонних библиотек;
— обычно распространяются в архивах (war, jar);
— в их структуре выделяют конфигурационную часть и, собственно, java-классы.
J2EE
Java Enterprise — звучит сильно, а? Но мы не можем сказать, что J2EE это очень мощный инструмент и всё такое прочее. Почему? Потому, что J2EE — это целая туча инструментов, спецификаций, API, и прочих радостей современной жизни.
Давайте посмотрим на основные разделы J2EE и программные продукты, которые их реализуют (внимания, слова Java и API в названиях опущены):
- Servlet — самый простой EE API. Реализует элементарную логику веб-приложения. Его основа — два понятия: Filter и Servlet;
- JSP — Java Server Pages. Это спецификация, описывающая язык страниц. В приложении они могут играть роль View, обычные сервлет-контейнеры умеют обрабатывать jsp-хи. Для них обычно запущен отдельный сервлет, передающий в страницу request и response — см. ниже.
- Persistence — API, обеспечивающий хранение данных. Сейчас самая популярная реализация — Hibernate, частично использующая свой собственный API.
- API для обмена сообщениями: JMS (некий почтоподобный протокол), RMI (набор классов для передачи данных/команд по сети) и другие
- Enterprise Java Beans — о, вы о скорее всего слышали. По сути это спецификация о том, как надо строить классы чтобы их было просто обслуживать автоматизированным инструментам — пересыльщикам сообщения, службам хранения, классам, контроллирующим многопоточность etc.
- Transaction — API, отвечающий за организацию транзакций. Признаюсь, не использовал;
- Portlet — API, упомянутое на хабре в отдельной статье. Основывается на разделении веб-страницы на участки и представления каждого в виде отдельного сервиса;
Итак, думаю вы получили представление о наборе стандартных средств. Кроме них, стоит упоминуть добрую сотню веб-морд (JSF, Tapestry5, Struts и прочее), которые с разными извращениями предлагают вам реализовать веб-интерфейс, предлагая всяческие вкусности и автоматизацию в обмен на
Структура простого J2EE-приложения выглядит так:
Контейнер сервлетов - Фильтр - Фильтр - ... - Фильтр - СервлетКонтейнер — некое приложение, например Apache Tomcat или Jetty. Оно служит для реализации веб-доступа к вашему приложению и отвечает за приём и распределение согласно конфигурации запросов, хранение сессий и за доступ к статичному контенту. Фильтры и сервлеты описываете вы, реализуя в них нужную вам логику. Помните, они должны уметь себя проинициализировать и похоронить. Кроме того, каждый фильтр при получении запроса должен либо пустить его дальше по цепочке фильтров (таким образом запрос «падает» до сервлета), обработать его самостоятельно или же отправить на другой сервлет, по другому адресу, для обработки. Сам же сервлет так же может перенаправить запрос, или же ответить на него.
Основные понятия в работе с сервлетами — запрос и ответ, request и response. По факту, они попадают к вам извне, ваша цель — написать тело ответа.
Теоретически, этого достаточно. В клинических случаях некоторые могут обойтись одними JSP и не использовать Сервлеты/Фильтры — подключаться к БД, доставать инфу и обрабатывать ошибки прямо в JSP. Но это — не правильно.
Да и просто реализовать Сервлет — не самая лучшая идея. Вам придётся самостоятельно доставать GET/POST-параметры из тела запроса и правильно сформировать заголовки ответа. Чтобы не заниматься вознёй есть специальный HttpServlet. Он сделает всё это за вас — вам остаётся только добавить заголовков и сформировать тело ответа и переопределить методы doGet/doPost, которые по умолчанию отдают сообщение об ошибке. Собственно, на формировании тела запроса вы и должны сконцентрироваться.
Таким образом, ваши задачи:
- привязывание сервлетов и фильтров к URL'ам (см. ссылку ниже);
- обработка запросов в сервлетах;
- реализация рутины (типа подсчёта кликов) в фильтрах;
- контроль зависимостей: при работе с веб-приложениями создаётся далеко не один class-loader, не забывайте таскать библиотеки;
- самостоятельная реализация хранения данных или делегация его какому-то готовому back-end'у типа того же Hibernate.
Что ж, надеюсь в этом месте вы уже поняли основной принцип работы J2EE-приложений. Однако, набор сервлетов и фильтров нужно ещё и как-то подставить сервлет-контейнеру.
Конфигурируем
Для распространения веб-приложений также служат зип-архивы, но на этот раз с расширением .war (web archive).
Структура у них такая:
/
WEB-INF/
web.xml - файл настройки приложения (<a href="http://www.javaworld.com/jw-10-1999/servletapi/web.xml">пример</a>)
classes/ - сюда кладём скомпилированные классы
lib/ - jar'ы c нужными библиотеками
http-контент (т.е. все html, css, js, jsp...)
Готовый war вы подкидываете в магическую папку (обычно webapps) вашего контейнера и перезапускаете его. Контейнер его распаковывает и вешает его содержимое на IP.в.настройках.контейнера: порт/имя_war'а/.
Весь контент из корня архива станет виден по соответствующему адресу.
Если заинтересовало — качайте Tomcat/Jetty — в их поставке есть набор примеров, на которых вы сможете потренироваться.
И ещё есть хороший туториал с простыми примерами. Рекомендуется хотя бы «чисто поглядеть».
J2ME
Казалось бы, мир J2ME не должен быть так же велик, как J2EE, правда? Вроде бы это не целая гора спецификаций да и цели другие… Однако, это не так. Здесь всё то же самое, но повязано на другом принципе: вы не можете выбрать набор библиотек, он определён телефоном. Здесь всё несколько интереснее.
Кроме обрезанного ядра Java (кроме всего прочего нету Java Collections Framework и в некоторых реализациях нет нецелых чисел), вы получаете набор реализованных API, так называемых JSR. Каждый имеет свой номер. По сути это небольшая библиотека, которая даёт телефону некоторый функционал. Например 82 отвечает за доступ к блютус из Java, 205 — даёт вам MMS и так далее. На самом деле большинство из них не относится к J2ME, например мы можем найти там даже спецификацию сервлетов, однако именно с J2ME выяснение набора поддерживаемых JSR становится необходимым.
Про все JSR-ки можно почитать на жутко официальном сайте.
Каждая J2ME-платформа состоит из двух основных компонент: профиля и конфигурации.
Конфигурации описывают API, реализующий внутрепрограммные операции, а профили — взаимодействие.
Конфигурации на телефонах используются две: CDC, CLDC. Они реализуют работу с потоками ввода-вывода, математическими функциями, исключениями и т.д. CLDC — более ограничена, в первой версии отсутствуют числа с плавающей точкой, слабые ссылки. В версии 1.1 (самой распространённой) эти возможности есть, но отсутствует сериализация и часть механизма Reflection.
Из профилей, для разработки MIDlet'ов используются MIDP — Mobile Information Device Profile. В него изначально входят классы для отображения мидлетов, GUI, а также систему хранения пользовательской информации RMS. В новых версиях (сейчас распространена 2.0 и в разработке находится версия 3.0) включена поддержка специфических для игр возможностей, а также поддержка мультимедиа. Кроме того, на многих телефонах реализована работа с файлами в хранилище телефона, а также API для сетевых взаимодействий — SMS, MMS, Bluetooth.
Структура программы J2ME напоминает J2SE: вы наследуете Главный Класс от MIDlet и пользуетесь магией вида
Display.getDisplay(экземпляр_мидлета).setCurrent(...)Таким образом вы подсовываете телефону некоторые экраны (Displayable, а обычно — GameScreen, у него удобнее всего ловить нажатия клавиш), за перерисовку которых отвечаете самоятоятельно. Вы можете рисовать картинки, текст, прямоугольники и ещё несколько геометрических фигур. Кстати, хорошая новость — J2ME абсолютно адекватно рисует полупрозрачные PNG.
Отдельная песня — отлов нажатий на кнопки. Реализация примитивная — на вход вы получаете число, соответствующее коду некой кнопки. В принципе, опытным путём (или из документации) они подбираются достаточно быстро, но здесь бывает подлянка: на некоторых телефонах коды кнопок могут отличаться. Этим грешат моторолы и LG.
К сожалению, боюсь я не смогу раскрыть всех прелестей программирования для мобилок. На самом деле это совершенно отдельный жанр. Работая с телефоном вы всегда должны заботиться о том, чтобы вашей программе было негде повиснуть и чтобы она не жрала память, которой может быть всего мегабайт-два. Кроме того, вы должны адекватно обрабатывать случаи, когда телефон пользователя имеет специфическое разрешение или не поддерживает нужный вам JSR. Да, ещё: для старых телефонов размер jar'а с приложением не должен превышать 300кб.
Конфигурация
Конфигурировать своё приложение вы должны в файле MANIFEST.MF в папке META-INF jar'а. Кроме того, полезно указать те же сведения о приложении в .jad файле — на некоторых телефонах это немного ускоряет загрузку. Формат есть в википедии,
Отладка
Для отладки таких приложений используется Sun Wireless Toolkit. Если некий производитель телефонов хочет выпустить эмулятор своего нового телефона, он берёт WTK, вешает на него свой скин и реализованные JSR-ки. Эмулятор готов.
К счастью, подцепить IDE к отладчику проблем не составляет, однако отлаженное в «тепличных условиях» приложение не всегда будет работать идеально на всех телефонах, поэтому на реальных моделях тоже стоит потестировать.
Пример отладки (извиняюсь за хреновое качество), но это был первый найденный скриншот из тех, что я не удалил.
А примерно вот так выглядит отладка на телефонах. На столе их 5 штук, не считая собственного :)
Что вы должны уметь для работы с J2ME:
- натренироваться рисовать интерфейс, постоянно рассчитывая всякие координатные смещения, выделенные объекты и прочее;
- прикидывать, когда какие объекты/картинки нужно выгрузить из памяти, чтобы её не забить;
- обходиться минимумом средств для реализации логики приложения;
- доставать ресурсы, например так:
Image.createImage("/test.jpg").
P.S. Если надумаете эксперементировать — гуглите по java tutorial j2me/j2ee — найдёте кучу примеров. В качестве IDE рекомендую триал IntelliJ IDEA, но подойдут и Eclipse/NetBeans.
Удачи вам, уважаемые читатели. Задавайте вопросы.



комментарии (25)