Книга 1 - Начальные сведения
Книга 2 - Более профессиональный подход |
Студенческий отдел кадров Пособие по JAVA-технологиям (с)
AntonSaburov Application Server & Enterprise Java Beans Ну,
поехали :). Именно
это подумал я, когда начал писать данный материал. Автору и читателям пришлось
немало потрудится прежде чем мы добрались до одного из очень интересных
разделов в множестве технологий Java. А именно до Application Server и Enterprise Java
Beans. Я очень
надеялся, что смогу обойтись без установки какого-либо IDE, но увы, время не стоит на
месте и не пользоваться такого рода системами уже не получается. Для такого
рода приложений приходится делать очень много ручной работы, которая может быть
охарактеризована таким выражением «за деревьями леса не видно». Я
постараюсь не оставлять вас в неведении по некоторым вопросам – даже полностью
сгенерированный код требует понимания. Но это уж как получится. Я
предлагаю закачать достаточно мощный пакет – (хорошо, что он бесплатный) – IDE
NetBeans 6.0. Закачать пакет можно по ссылке NetBeans 6.0 Очень
советую (и настойчиво прошу) закачивать полную версию. Да, она не маленькая –
169 Мб – но Вы не пожалеете. К тому же я все примеры буду проводить именно под
такой версией. В
принципе можно закачать вариант «Web & Java EE», но все-таки цикл статей
будет постоянно расти. И возможно мы дойдем до SOA (Service Oriented Architecture). Это совсем молодая технология,
которая будет развиваться в ближайшие годы. И если Вы успеете понять основные
принципы и ознакомитесь с основными моментами, то Ваш профессиональный рост
совершит резкий скачок. Установка
NetBeans не должна вызвать у вас проблем, поэтому на этом моменте я не
буду останавливаться. Единственное замечание по установке – БУДЬТЕ ВНИМАТЕЛЬНЫ
ПРИ ЗАДАНИ ПАРАМЕТРОВ для GlassFish – я имею в виду
логин/пароль. В принципе может взять парметры по умолчанию: login – admin password – adminadmin
GlassFish - это Application Server,
который идет вместе с NetBeans и является разработкой Sun. GlassFish
– вполне современный Application Server,
который поддерживает новейшие технологии исамые последние спецификации от Sun. Так
что пользуйтесь и получайте удовольствие. И
еще одно – мой вам совет – создайте пароль для пользователя root
в MySQL
– это не
сложно. Надо будет запустить нижеприведенный SQL и больше никаких забот. GRANT ALL ON students.*
TO 'root'@'%' IDENTIFIED BY 'root'; Пароль
стал = root Я уже
не раз сталкивался. что некоторые системы не очень понимают ситуацию, когда
пароль отсутствует. Так что во избежание проблем сделаем это несложное
действие. А
теперь мы поговорим о том, что же такое Application Server. Application Server (AppServer) Идея
AppServer родилась уже не так уж мало лет назад. Уже более
12-15 лет назад разработчики высказывали идею, что надо иметь некий сервис,
который возьмет на себя некоторые задачи – например распределение нагрузки,
соединения с базами данных, причем сразу с несколькими, систему сообщений,
систему аутентификации и авторизации, управление различными ресурсами. И самое
главное (на мой взгляд) – возможность удобно размещать бизнес-логику.
Бизнес-логика на клиенте – это очень мощные рабочие станции, которые будут
требовать огромные ресурсы. С другой стороны помещать всю бизнес-логику в базу
данных – не получается. Т.к. может быть использована не одна, а десятки баз
данных на разных хостах. Значит нужен некий программный продукт, который
позволит удобно управлять написанными приложениями. Именно
такую задачу берет на себя Appication Server.
На сегодня Java является наверно самой развитой системой, под которую создажются
такого рода Application Server’а. Комания
Sun создала спецификацию, которая описывает те сервисы и те
прпавила, по которым AppServer должен работать. На
первое время я Вам советую воспринимать AppServer как некое хранилище классов,
которые просто зарегестрированы на нем специальным образом под именами (да-да,
это тот самый JNDI с которым мы сталкивались некоторое время назад). Раньше для
регистрации требовалось создавать специальный XML-файл – ejb-jar.xml. Уже
тогда существовали специальные средства для автоматизации этого процесса. Для
новой спецификации все стало еще проще. В чем Вы скоро убедитесь. Клиентское
приложение спрашивает у AppServer’а класс по имени, получает
его (если он конечно есть) и использует. И
выполняется этот класс под управлением AppServer’а. Именно AppServer берет
на себя задачу запуска класса в отдельном треде, берет на себя задачу поставки
всевозможных ресурсов – коннекты к базе данных, вызовы Web-Services и многое другое. Клиент
получает ссылку на интерфейс, за которым прячется настоящий класс. И эту ссылку
клиент получает у ApplicationServer’а. Возможно
мы еще вернемся к обсуждениею возможностей AppServer’ов, но здесь слов пока
достаточно. Настало
время поговорить немного о приложениях, которые выполняются под управлением AppServer’а.
А именно об Enterprise Java Beans
– EJB. Мы
будем работать с EJB 3.0. Спецификация для EJB 3.0 стала более зрелой и
более удобной для работы. Если Вам захочется ознакомиться с более старыми
спецификациями, то заходите на сайты в Интернете и ищите информацию. Но это уже
выходит за рамки данного цикла статей. Сам
по себе бин не представляет из себя каких-либо сложностей – это просто класс,
который зарегестрирован на AppServer’е и обладает определенным
набором характеристик. Существует
три вида бинов:
Application Server также включает в себя
интерфейс, который реализует бин. И именно интерфейс будет представлен клиенту.
А сам бин будет спрятан в недрах сервера. Что
еще важно понять, так это способы вызова бинов. Ведь по сути они все тихо и
мирно лежат в границах AppServer’а, который их и вызывает по
заданию от клиентов. В самой первой спецификации было принято решение, что
каждый клиент является отдельной Java-машиной. Но такой вызов
очень «дорогой». Он требует некоего механизма, который позволит передавать
данные из одной JAVA-машины в другую. Очень ресурсоемкое решение.
Поэтому было принято решение, что надо создать два типа вызовов – локальный и
удаленный (Local и Remote). Локальный
вызов происходит тогда, когда клиент тоже является по сути бином на том же AppServer’е.
Удаленный – как и раньше, это другая Java-машина. В
этой статье не ставится задача подробно рассказать о возможностях и
теоретических построениях – здесь мы сосредоточимся на практике. Поэтому
отложим пока сложные книжки по EJB в сторону и напишем наше
первое приложение. Разработка Enterprise приложения Мы
с вами начнем фактически с нуля. Да-да. Вы можете забыть про свой замечательный
код и оставить только базу данных MySQL, которая нам понадобится. Возможно
у нас получится использовать JSP и кое-какую логику из наших
сервлетов. Все остальное изменится достаточно сильно. На
сегодня в какой-то степени некоторое понятие Enterprise-приложения сложилось.
Конечно, содержимое таблиц да и сами таблицы, бизнес-логика – дело сугубо
личное. Но есть несколько моментов, которые являются общими. Их мы и
рассмотрим. А чуть позже и увидми в нашем «Отделе кадров». Основными
составляющими Enterprise-приложения являются:
В
данной части мы не будем создавать приложение целиком. Во-первых – слишком
много материала. А во-вторых – у меня есть тайное желание, чтобы Вы сами
попробовали что-то сделать. Возможно, что к тому времени как будет написана
часть где мы сделаем наше приложение более-менее рабочим, Вы сами уже его
напишете. Мне будет очень приятно об этом услышать. EJB-часть Ну,
давайте запустим NetBeans. Если
Вы сделали это первый раз, то перед Вами появится замечательная картинка.
Не
будем долго обсуждать достоинтсва и недостатки NetBeans. Возьмем быка за рога. 1.
Выбираем пункт меню File->New Project… В
появившемся диалоговом окне в дереве Categories выбираем Enterprise.
В появившемся списке Projects Выбираем первый пункт – Enterprise Application. Жмем кнопку Next
2.
Вводим имя проекта StudentsApp и жмем кнопку Finish. Обратите
внимание на путь до проекта и отмеченные пункты “Create EJB
Module” и “Create Web Application Module”. Как
Вы возможно уже догадались это те самые части, о которых я упоминал выше – Application Server и Web Server.
3.
У вас должен появиться вот такой экран. Я Вам советую походить по дереву
проекта. Просто из любопытства.
Уже
хорошо видно, что наше Enterprise-приложение включает в себя
два модуля – EJB и WEB. Я очень советую привыкать думать о них постоянно J Поехали
дальше. Теперь мы создадим два класса (Entity) которые будут являтся
«отражением» наших таблиц – groups и students. Для этого щелкните правой
кнопкой мыши на проекту StudentsApp-ejb, выбирайте New->Entity
Classes from Database. У вас откроется диалоговое
окно в котором надо будет выбрать DataSource. Нужного нам DataSource конечно
же пока нет, пожтому выбираем пункт New Data
Source (см. на рисунок)
В
этом случае нам опять предложат диалоговое окно, где нужных нам параметров
опять же нет и опять же нам надо выбрать New Database Connection.
И
снова NetBeans помогает нам показывая очередное окошко. Здесь мы установим уже
нужные нам параметры для соединения. ВНИМАНИЕ
!!! Установите флаг на чекбоксе “Remember password”
– иначе подсоединение не получится.
Если
Вы не ошиблись с набором, то должно быть выдано вот такое окно (вернее это тоже
самое окно, просто следующая закладка)
Нажмем
OK, попадем в окошко создания Data Source,
где будут указаны параметры для нашего источника данных. Снова жмем OK. Если
Вы не допустили ошибок, то перед Вами дожно появиться вот такое вот окошко
Переносим
обе таблицы направо и жмем Next. Теперь
перед Вами вот такая вот информация. Обратите внимание – я не снял галочку в чекбоксе “Generate Named Query Annotation for Persistent Fields”. Нам
такого рода запросы не потребуются (во всяком случае пока), но от нас не убудет
J Также
обратите внимание на имя пакета, которе я ввел. Вы можете конечно же
использовать свое собственное, но тогда Вам придется это учитывать. Не
советую также менять название классов – проблема в том, что слово Group
имеет важное значение и использовать его не рекомендуется. Поэтому оставляем во
множественном числе. Кстати это напоминание нам (уже в который раз) не
использовать «подозрительные» слова для имен. «Подозрительные» - это значит.
что они могут быть использованы как keywords в каком-нибудь языке.
В общем, используйте префиксы господа
Жмем
кнопку Finish и видим, что у нас появилось два класса – Groups
и Students.
Я не буду приводить их код. Во-первых не хочется загромождать текст статьи, а во-вторых
– да в общем-то нам он пока мало интересен. Он сгенерился и пока этого
достаточно. Также
я обратил бы Ваше внимание на файл sun-resources.xml (поищите его в дереве) – там
вы увидите наши замечательные параметры. Если внимательно посмотреть, то мы
увидим и URL для соединения, и логин и пароль. Но
это еще не все, что нам необходимо для работы с базой данных. В EJB 3.0
появилось такое понятие как Persistence Unit. По
сути это XML файл, который описывает параметры для подсоединения к базе данных.
После того, как мы его создадим поговорим и о нем. Итак,
опять нажимаем правую кнопку мыши на StudentsApp-ejb, выбираем New->Other
(скорее всего у Вас не будет пункта Persistence Unit, но
если он есть – выбирайте его сразу). В появившемся окошке выбираем Persistence и
Persistence Unit. Жмем Next.
В
слудующем окне визарда мы увидим картинку, которая представлена ниже. Обратите
внимание на установленные параметры. Во-первых это Data Source.
Он выбирается из списка и равен тому, который мы создали ранее. Во-вторых
группа “Table Generation Strategy”
установлена в None. Таблицы у нас уже есть, так что нам не требуется их создавать
заново. Для
тех, кто уже знает, что такое Hibernate – он тоже есть в списке Persistence Provider. Но о нем в другой раз. Пока возьмем вариант
по умолчанию – TopLink.
Сразу
после создания Вы можете посмотреть на файл, который создался – посмотрите,
поищите знакомые черты. давайте
поразмышляем над тем, что же мы такое создали ? В двух словах мы сделали
следующее:
Что
нам осталось для того, чтобы полностью восстановить логику нашего приложения ?
Я думаю. что уже болшинство из вас догадалось – надо создать класс managementSystem в котором будут нужные нам методы по редактированию и получению данных.
Давайте и создадим его. Правда
теперь это будет не просто класс, а класс SessionBean, который будет работать под
упарвлением AppServer’а. И пользоваться всеми благами этого. Опять
парвая кнопка на StudentsApp-ejb, выбираем New->Session
Bean… Снова
перед нами диалоговое окно, в котором мы наберем имя класса ManagementSystem.
По умолчанию нам будет предложено выбрать только Local-интерфейс. Предлагаю пока
оставить как есть – может у нас хватит пороху добраться до создания отдельного
удаленного Java-клиента, но тогда нам никто не помешает его создать.
Мы
получим сразу два файла:
Давайте
теперь создадим один метод – getStudents. Он будет возвращать нам
одного студента по его ID. если
у Вас не открыт в редакторе файл ManagementSystemBean.java – откройте. Теперь
щелкаем правой кнопкой где-нибудь на поле редактора и выбираем пункт EJB
Methods->Add Business Method. Появиться
очередное диалоговое окно, в котором мы введем имя метода, тип возвращаемого
значения и добавим входной параметр (Использйте кнопку Add справа). Введите имя и тип
нашего параметра.
Если
Вы откроете в редакторе оба файла - ManagementSystemBean.java и ManagementSystemLocal.java, то
увидите, что там есть ошибка. Нам укажут, что необходимо сделать импорт класса Students.
Самым простым решением будет кликнуть левой кнопкой на символ ошибки в самом
левом столбце редактора и выбрать пункт “add import
for students.entity.Students”. Но
пока кода для обращения к базе данных у нас нет. Так как же мы будем получать
нашего хорошего студента ? Оказывается это тоже очень несложно. Щелкаем
правой кнопкой мыши в редакторе ManagementSystemBean.java и выбираем пункт Persistence->Use
Entity Manager. И
вот теперь я представлю код нашего класса ManagementSystemBean.java package students.logic; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import students.entity.Students; @Stateless public class ManagementSystemBean implements
ManagementSystemLocal {
@PersistenceContext private
EntityManager em; public
Students getStudents(int studentId) { return em.find(Students.class,
studentId); } public void
persist(Object object) { em.persist(object); } } Я
убрал комментарии, а все остальное оставил. Единственное, что я еще сделал –
изменил метод getStudents. Здесь
Вы можете видеть в действии нововведение от Java .1.5 – аннотации. Аннотации
предназначены для облегчения «чтения» кода. Я взял слово «чтения» в кавычки
потому, что оно подразумевает, что не только человек будет читать код, но и
компилятор читает, и даже JVM это делает в момент
исполнения. Аннотация
@PersistenceContext по сути создает контекст в
рамках которого может быть произведена работа с базой данных. Sun
постарался как
можно дальше «отодвинуть» разработчиков от писанины кода и заменил всевозможные
вызовы для подключения на такую вот простую форму. Класс
EntityManager – это интерфейс (если Вы посмотрите в JEE
API). Как мы уже знаем интерфейс не может ничего делать. А значит
за ним кроется настоящий класс. Который умеет работать с базой данных. Значит
наша аннотация делает достаточно много вещей: она создает и инициализирует
объект определенного класса (причем этот объект создается путем обращения к AppServer’у),
который реализует интерфейс EntityManager. Если вы внимательно
посмотрите файл persistence.xml (смотрите вариант не кода XML, а Design),
то увидите пункт Persistence Provider – то реализация интерфейса.
По умолчанию используется TopLink. В общем-то
основные шаги для того, чтобы запустить наше приложение на AppServer’у
мы сделали. Осталось только добавить WEB-интерфейс в виде простого
сервлета – так кто нам мешает ? WEB-часть Давайте
сделаем очень простое WEB-приложение. Пусть у нас на
главной странице будет форма для ввода studentID и кнопка для вызова
сервелета, который покажет нам данные о студенте. Откройте
проект StudentsApp-war и найдите там файл index.jsp. Мы
внесем в него немного изменений. Теперь
он будет выглядеть вот так: <%@page contentType="text/html"
pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta
http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<title>JSP Page</title>
</head> <body>
<h2>Hello World!</h2> <form
action="MyServlet">
<input name="studentId" type="text"/>
<input type="submit" value=”Show”/> </form> </body> </html> Обратите
внимание, что мы будем вызвать наш сервлет по URL /MyServlet Теперь
надо создать наш сервелт. Кликнем правой кнопкой на проекте StudentsApp-war и
выберите New->Servlet Заполните
поля как показано на рисунке и нажмите Next
Убедитесь,
что Ваш следующий экран похож на следующий рисунок и нажмите Finish
Теперь
нам надо добавить в наш сервлет получение данных о студенте по данному
параметру. Мы не будем делать какие-либо проверки – это конечно не хорошо, но
мы же пока просто пробуем. В итоге наш сервлет будет таким package students.web; import java.io.*; import java.net.*; import javax.ejb.EJB; import javax.servlet.*; import javax.servlet.http.*; import students.entity.Students; import students.logic.ManagementSystemLocal; public class MyServlet extends HttpServlet { @EJB private
ManagementSystemLocal ms; protected
void processRequest(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter(); try {
Students d =
ms.getStudents(Integer.parseInt(request.getParameter("studentId")));
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet
MyServlet</title>"); out.println("</head>");
out.println("<body>");
out.println("<h1>Student:["+d.getFirstName()+","+d.getSurName()+"]</h1>");
out.println("</body>");
out.println("</html>"); }
finally {
out.close(); } } protected
void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
processRequest(request, response); } protected
void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
processRequest(request, response); } public
String getServletInfo() { return
"Short description"; } } Вам
необходимо обратить внимание всего на несколько строк:
Чтобы
Вам было немного интереснее, я приведу Вам пример кода вызова бина более старой
спецификации InitialContext ctx
= new
InitialContext(); Object obj
= (Object) ctx.lookup("java:comp/env/ejb/ManagementSystem
"); ManagementSystemHome home
= (ManagementSystemHome) PortableRemoteObject.narrow(obj, ManagementSystemHome.class); ManagementSystemHome ms
= home.create(); Ну как ощущения ? Причем
я Вам показал локальный вызов – при удаленном пришлось бы еще указывать для InitialContaxt
дополнительные параметры. Вторая строка создает ссылку на так называемый Home-интерфейс
– этот объект отвечал за создание реального объекта. И его тоже надо было делать.
Третья строка приводила тип и только четвертая создавала нужный нам объект. И
такое надо было делать при каждом вызове объекта на стороне ApplicationServer’а.
Занятие мало интересное. И как Вы прекрасно видите вполне автоматизируемое. Что
и было сделано в новой специфиакции. Теперь
мы должны собрать наш проект и запустить. Для этого выполняем пункты меню:
По
идее у вас должно получится вот такой экран в броузере
Теперь
введите корректный ID для студента (это на Вашу
ответственность) и ... вуаля. Ну такой вот у меня не очень удачный студент с
именем и фамилией [d,s]
Ну
вот мы прошли самый простой путь создания настоящего Enterprise приложения. В следующей части
мы с вами упрочим наши знания. Хотя как я уже говорил выше, Вы можете
попробовать уже сами сделать все необходимое. Но
все-таки давайте немного углубимся в некоторые детали - Часть
12 - AppServer и EJB - копаем вглубь |