IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  Технология Java | Open source  >

Работа с Grails: Cоздание первого Grails-приложения

Узнайте, как много возможностей заключено в этой маленькой инфраструктуре для разработки Web-приложений

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются

Обсудить


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: простой

Скотт Дэвис, главный редактор, AboutGroovy.com

21.09.2009

Программистам на Java™ не нужно отказываться от своего любимого языка и существующей инфраструктуры для разработки, чтобы воспользоваться современной инфраструктурой для разработки Web-приложений. В первой части новой ежемесячной серии статей "Работа с Grails" эксперт по Java Скотт Дэвис знакомит с Grails и показывает, как построить первое Grails-приложение.

Знакомство с Grails я начну с другой бесплатной инфраструктуры для разработки Web-приложений: Ruby on Rails. Когда Rails появился, он увлек множество разработчиков. Возможности скаффолдинга, заложенные в Rails, позволяли запустить новый проект за меньшее время, чем раньше. Идея "соглашений по конфигурации" (convention over configuration), лежащая в основе Rails, позволяет приложению "собирать" себя самому, основываясь на разумных схемах именования, а не на громоздких и подверженных ошибкам конфигурационных XML-файлах. Возможности метапрограммирования Ruby позволяют объектам "магически" наследовать методы и поля, которые им требуются во время работы, без загромождения исходного кода.

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

Об этой серии статей

Grails - это современный инфраструктур для разработки Web-приложений, который сочетает известные Java-технологии, такие как Spring и Hibernate, с современными приемами, такими как "соглашение по конфигурации". Написанный на Groovy, Grails прозрачно интегрируется с существующим Java-кодом, добавляя гибкость и динамику языков сценариев. После изучения Grails ваши взгляды на разработку Web-приложений изменятся бесповоротно.

Здесь на сцену выходит Grails. Grails предоставляет те же возможности разработки, что и Rails, при этом сохраняя прочную связь с проверенными Java-технологиями. Но Grails - это не просто "еще один клон" Rails, перенесенный на платформу Java. Grails усвоил уроки, полученные в Rails, и соединил их с современными веяниями в Java-программировании. Это скорее развитие Rails, чем просто перенос на новую платформу.

Открывая цикл "Работа с Grails", эта статья знакомит с инфраструктурой Grails, показывает, как установить ее, и шаг за шагом показывает процесс создания первого Grails-приложения: планировщика поездок, который будет использоваться в последующих статьях этой серии.

Возможности Groovy

Так же как Rails глубоко привязан к языку программирования Ruby, Grails не смог бы существовать без возможностей Groovy (см. раздел Ресурсы). Groovy - это динамический язык, работающий в JVM и прозрачно интегрирующийся с языком Java. Если вы читали многолетний цикл статей Practically Groovy на Web-сайте developerWorks, то вы уже знакомы с возможностями этого языка. Если же нет, то ничего страшного, в процессе изучения Grails придется узнать очень много и о Groovy. Это не должно быть сложно, так как Groovy был специально спроектирован так, чтобы понравиться Java-разработчикам.

Например, Groovy позволяет существенно сократить количество Java-кода, который обычно приходится писать. Не требуется писать get и set-методы для доступа к полям, так как Groovy предоставляет их автоматически. Не нужно писать конструкции типа for Iterator i = list.iterator() для выполнения цикла по списку элементов; конструкция list.each делает то же самое более лаконично и наглядно. Проще говоря, Groovy - это то, как выглядел бы язык Java, если бы его написали в двадцать первом веке.

Groovy никогда бы не привлек Java-программистов, если бы для того, чтобы воспользоваться его преимуществами, приходилось полностью переписывать приложения. К счастью, Groovy прозрачно интегрируется с существующим кодом. Язык Groovy не заменяет язык Java, а усовершенствует его. Groovy можно быстро изучить за один день, так как Groovy-код - это Java-код. Эти два языка настолько совместимы, что можно переименовать работающий файл .java в файл .groovy (например, файл Person.java переименовать в Person.groovy), и получить абсолютно правильный (и исполняемый) файл Groovy, хотя он и не будет использовать никаких синтаксических преимуществ, предоставляемых Groovy.

Такая глубокая совместимость между языками Groovy и Java означает, что Grails не нужно "изобретать колесо", когда речь идет о ключевых внутренних технологиях. Вместо этого он позволяет взглянуть на знакомые Java-библиотеки с точки зрения Groovy. Сценарии тестирования JUnit типа TestCase заключаются в Groovy-оболочку и представляются как объекты типа GroovyTestCase. Grails представляет новую точку зрения на сценарии сборки Ant посредством GANT - версии Ant, реализованной исключительно на Groovy. Grails помещает Hibernate за "тонкий" Groovy-фасад, называемый GORM (Grails Object Relational Mapping - расширение Grails для объектно-реляционного преобразования). Это только три примера того, как Grails позволяет использовать весь опыт, накопленный в Java, одновременно предоставляя преимущества современных приемов Web-разработки.

Но чтобы полностью оценить Grails, для начала с ним необходимо познакомиться на практике. Пришло время установить Grails и создать первое Web-приложение.



В начало


Установка Grails

Все, что требуется для запуска Grails-приложения, заключено в один ZIP-файл. Все зависимые библиотеки - Groovy, Spring и Hibernate и многие другие - уже установлены на место и готовы к использованию. Для установки Grails необходимо:

  1. Скачать и распаковать архив grails.zip с Web-сайта Grails (см. раздел Ресурсы).
  2. Установить переменную среды GRAILS_HOME.
  3. Добавить путь $GRAILS_HOME/bin в переменную среды PATH.

Конечно, необходимо иметь установленную версию JDK. (Grails хорош, но все-таки не настолько хорош). Grails 1.0 может запускаться на Java 1.4, 1.5 и 1.6. Если неизвестно, какая версия установлена, введите java -version в командной строке. Если необходимо, скачайте и установите версию JDK, совместимую с Grails (см. раздел Ресурсы).

После выполнения действий по установке необходимо ввести в командной строке grails -version для проверки правильности установки. Если выводится следующее приветственное сообщение, значит, все настроено правильно:

Welcome to Grails 1.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /opt/grails

Web-сервер и база данных в комплекте

Использование бесплатных продуктов

В приложении в этой статье будут использоваться Web-сервер и база данных, которые бесплатно поставляются с Grails. В следующей статье будут представлены пошаговые инструкции по запуску Grails на других серверах. Также можно посетить Web-сайт grails.org и ознакомиться с отличной онлайновой документацией (см. раздел Ресурсы).

Интересно, что для запуска Grails-приложений не требуется отдельно установленного Web-сервера. Grails поставляется со своим встроенным сервлет-контейнером - Jetty. Достаточно ввести grails run-app, и приложение будет запущено в контейнере Jetty (см. раздел Ресурсы) без необходимости проходить через обычные этапы установки. Запуск Grails-приложения на существующем корпоративном сервере приложений также не представляет проблем. Если ввести команду grails war, будет создан стандартный файл, который можно установить на Tomcat, JBoss, Geronimo, WebSphere® или любой другой сервлет-контейнер, совместимый с Java EE 2.4.

Также не требуется отдельно установленной базы данных. Grails поставляется с базой данных HSQLDB (см. раздел Ресурсы), написанной полностью на Java. Наличие базы данных, уже готовой к использованию, дает существенную прибавку к продуктивности. Использовать другую СУБД, например, MySQL, PostgreSQL, Oracle Database или DB2 также несложно благодаря Hibernate и GORM. Если имеется JAR-файл с JDBC-драйвером и настройки для стандартного подключения, то достаточно внести одно изменение в файл DataSource.groovy, чтобы переключить приложение на использование другой базы данных.



В начало


Создание первого Grails-приложения

Мне приходится много путешествовать - по меньшей мере 40 поездок в год. Я обнаружил, что календари оказывают мне огромную помощь, говоря мне, когда я должен быть где-то, но при этом не сообщают, где находится это место. У онлайновых карт противоположная проблема: они отлично справляются с вопросом "где", но не с вопросом "когда". Поэтому в этой и паре последующих статей этой серии будет подготовлено специальное Grails-приложение, которое поможет решать вопросы "где" и "когда" при планировании поездки.

Осторожно, спойлер!

Вам не кажется, что в следующих статьях этой серии будет рассматриваться совместное использование Grails вместе Google Calendar и Google Maps? Мне кажется....

Для начала необходимо войти в пустой каталог и ввести команду grails create-app trip-planner. После вспышки активности можно будет увидеть каталог trip-planner. Подобно Maven, Rails и AppFuse, Grails создает стандартную структуру каталогов для пользователя. Если вам кажется, что это безнадежно ограничивает вас, а с инфраструктурой невозможно работать, если вы не можете педантично создать собственное дерево каталогов, то, скорее всего, большого удовольствия от работы с Grails вы не получите. Соглашение, первая составляющая принципа "соглашение по конфигурации", позволяет взять любое Grails-приложение и немедленно понять, какие компоненты имеются и где они хранятся.

Далее необходимо перейти в каталог trip-planner и ввести команду grails create-domain-class Trip. Если все пройдет нормально, появятся два файла: grails-app/domain/Trip.groovy и grails-app/test/integration/TripTests.groovy. Тестирование будет рассматриваться в следующей статье. Пока же сфокусируемся на доменном классе, который начинается, как показано в листинге 1:


Листинг 1. Доменный класс, сгенерированный Grails
                
class Trip{

}

Пока смотреть не на что, но мы это исправим, добавив поля в класс Trip, как показано в листинге 2:


Листинг 2. Класс Trip с добавленными полями
                
class Trip { 
  String name
  String city
  Date startDate
  Date endDate
  String purpose
  String notes
}

Как уже говорилось, не нужно беспокоиться о создании get() и set()-методов, так как Groovy динамически сгенерирует их. Класс Trip также содержит много новых и полезных динамических методов, названия которых говорят сами за себя:

  • Trip.save() сохраняет данные в таблицу Trip в базе данных HSQLDB.
  • Trip.delete() удаляет данные из таблицы Trip.
  • Trip.list() возвращает список объектов Trip.
  • Trip.get() возвращает один экземпляр Trip.

Все эти и другие методы находятся в полном вашем распоряжении. Отметим, что класс Trip не расширяет родительский класс и не реализует "волшебный" интерфейс. Благодаря возможностям метапрограммирования Groovy эти методы просто появляются в соответствующем месте в соответствующих классах. (Эти методы, связанные с сохранением данных в базу данных, получают только классы в каталоге grails-app/domain).

Создание контроллера и видов

Создание класса для доменной области - это только первый шаг. Каждой модели для полноты картины требуется хороший контроллер и несколько видов. Предполагается, что читатель уже знаком с шаблоном MVC (Model-View-Controller - Модель-вид-контроллер) (см. раздел Ресурсы). Введите в командной строке: grails generate-all Trip, чтобы создать класс grails-app/controllers/TripController.groovy и соответствующий набор GSP-страниц (Groovy Server Pages - серверные страницы Groovy) в каталоге grails-app/views/Trip. Для каждого действия типа list в контроллере есть соответствующий файл list.gsp. Для действия create есть файл create.gsp. Здесь на практике становятся видны преимущества "соглашения по конфигурации": не требуется никаких XML-файлов для установления соответствия элементов. Каждый класс доменной области имеет пару в виде контроллера с соответствующим именем. При желании эту конфигурацию, основывающуюся на именах, можно обойти, но в большинстве ситуаций достаточно просто следовать соглашению, и приложение сразу заработает.

Рассмотрим файл grails-app/controller/TripController.groovy, показанный в листинге 3:


Листинг 3. Класс TripController
                
class TripController {
    ...
    def list = {
        if(!params.max) params.max = 10
        [ tripList: Trip.list( params ) ]
    }
    ...
}

Первое, что скорее всего заметят Java-программисты, это то, как много действий выполняет такой компактный код. Например, рассмотрим действие list. Самое важное происходит на последней строке этого метода. Grails возвращает коллекцию типа HashMap, содержащую единственный элемент с именем tripList. (Последняя строка в методе Groovy - это неявное выражение return. При желании можно напечатать слово return явно). Элемент tripList - это объект типа ArrayList, содержащий объекты типа Trip, извлеченные из базы данных методом Trip.list(). Обычно этот метод возвращает все записи из таблицы. Строка, расположенная над этой строкой, говорит: "если кто-нибудь передаст в URL параметр с именем max, необходимо на основании его значения ограничить количество возвращенных объектов Trip. Если такого параметра нет, то ограничить количество объектов Trip десятью". URL-адрес http://localhost:8080/trip-planner/trip/list вызывает эту функциональность. Например, URL-адрес http://localhost:8080/trip-planner/trip/list?max=3 покажет только три поездки вместо обычных десяти. Если еще имеются поездки, которые можно показать, то Grails автоматически создаст ссылки для перехода на страницы со следующими и предыдущими наборами элементов.

Так где же используется эта коллекция типа HashMap? Рассмотрим файл grails-app/views/list.gsp, показанный в листинге 4:


Листинг 4. Файл list.gsp
                
<g:each in="${tripList}" status="i" var="trip">
  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
    <td>
      <g:link action="show" id="${trip.id}">${trip.id?.encodeAsHTML()}</g:link>
    </td>
  </tr>
</g:each>

Файл list.gsp - это по сути простой HTML документ с небольшим количеством GroovyTagLibs (библиотек Groovy-тегов). Все, перед чем стоит префикс g:, является Groovy-тегом. В листинге 4 тег <g:each> проходит по всем объектам Trip в коллекции tripList типа ArrayList и строит таблицу, соответствующую синтаксису HTML.

Чтобы понять, как работают контроллеры, необходимо разобраться с "тремя R": return (вернуть), redirect (перенаправить) и render (сформировать графическое отображение). Некоторые типы действий используют преимущества неявного выражения return, чтобы возвращать данные на GSP-страницу с таким же именем. Другие действия выполняют перенаправление. Например, действие типа index вызывается, если пользователь не указал тип действия в URL:

def index = { redirect(action:list,params:params) }

В этом случае класс TripController выполняет перенаправление к действию list, передавая при этом все параметры (или объект типа QueryString (строка запроса)) в коллекции params типа HashMap.

Наконец, действие типа save (см. листинг 5) не имеет соответствующей страницы save.gsp. Оно перенаправляет пользователя на страницу действия show, если запись была сохранена в базу данных без ошибок. В противном случае оно отображает страницу create.gsp, где можно увидеть возникшие ошибки и попробовать выполнить действие снова.


Листинг 5. Действие типа save
                
def save = {
  def trip = new Trip(params)
  if(!trip.hasErrors() && trip.save()) {
    flash.message = "Trip ${trip.id} created"
    redirect(action:show,id:trip.id)
  }
  else {
    render(view:'create',model:[trip:trip])
  }
}

Однако вместо того чтобы просто обсуждать, как работает Grails, стоит увидеть его в действии.



В начало


Работающее приложение

Введите grails run-app в командной строке. После набора сообщений Log4J, выведенных в консоль, должно быть показано сообщение с таким текстом:

Server running. Browse to http://localhost:8080/trip-planner

Если на порту 8080 уже находится запущенный сервер, в результате сбоя будет выведен дамп ядра с сообщением:

Server failed to start: java.net.BindException: Address already in use

Есть два способа легко изменить порт, на котором работает Jetty. Можно выполнить это изменение буквально на лету, введя команду grails -Dserver.port=9090 run-app. Чтобы сделать это изменение постоянным, необходимо в файле $GRAILS_HOME/scripts/Init.groovy найти строку, которая начинается с serverPort, и изменить ее значение:

serverPort = System.getProperty('server.port') ? 
             System.getProperty('server.port').toInteger() : 9090

После того как Grails был запущен на выбранном порту, можно ввести URL в Web-браузер. При этом должна появиться страница приветствия со списком всех контроллеров, как показано на рисунке 1:


Рисунок 1. Экран приветствия Grails-приложения
Рисунок 1. Экран приветствия Grails-приложения

Затем необходимо нажать на ссылку TripController, и вам будет представлено полноценное CRUD-приложение (Create, Read, Update, Delete - создать, считать, обновить, удалить), с которым уже можно работать.

Новые поездки создаются с помощью страницы, изображенной на рисунке 2:


Рисунок 2. Страница Create Trip (создать поездку)
Рисунок 2. Страница Create Trip (создать поездку)

Редактирование поездок производится с помощью страницы, изображенной на рисунке 3:


Рисунок 3. Страница Trip List (список поездок)
Рисунок 3. Страница Trip List (список поездок)

Так сколько же времени потребовалось на создание и запуск приложения? И сколько для этого потребовалось строк кода? Узнать об этом можно следующим способом:

  1. Нажать Ctrl-C для выключения Grails.
  2. Ввести grails stats.

На экране будут напечатаны следующие данные:

  +----------------------+-------+-------+
  | Name                 | Files |  LOC  |
  +----------------------+-------+-------+
  | Controllers          |     1 |    66 | 
  | Domain Classes       |     1 |     8 | 
  | Integration Tests    |     1 |     4 | 
  +----------------------+-------+-------+
  | Totals               |     3 |    78 | 
  +----------------------+-------+-------+

Для реализации всей функциональности приложения потребовалось менее 100 строк кода. Неплохо, но перед завершением статьи хотелось бы продемонстрировать еще одну возможность Grails.

Генерация контроллера и видов - это отличное упражнение, а наличие физических файлов на диске иллюстрирует, как все детали связаны между собой. Однако давайте удалим содержимое класса TripController и заменим его следующим содержимым:

  class TripController{
    def scaffold = Trip
  }

Эта единственная строка кода указывает Grails сделать то же самое, что было сделано с предыдущим контроллером, с одним исключением: сгенерировать все действия list, save и edit динамически - прямо в памяти во время выполнения. Три строки кода вместо 66 приводят к абсолютно такому же поведению приложения.

Снова введите grails run-app. Да, все введенные данные пропали, но это не страшно. Выключите Grails комбинацией клавиш Ctrl-C и напечатайте в командной строке grails prod run-app. Приложение будет запущено в рабочем режиме, что означает, что данные будут сохраняться между перезапусками сервера. Снова пройдем через TripController и сохраним несколько записей. В поведении приложения не заметно никакой разницы. Понимание того, что все, что показывается в Web-браузере, обеспечивается 15 строчками кода, дает представление о силе и возможностях Grails.



В начало


Заключение

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

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

Пока же рекомендую поупражняться с Groovy и Grails и уверяю, что ваши взгляды на Web-разработку радикально изменятся.



Ресурсы

Научиться
  • Mastering Grails: Build your first Grails application: оригинал статьи (EN).

  • Grails: Web-сайт, посвященный Grails.

  • Practically Groovy: : серия статей на страницах developerWorks, в которой исследуется практическое использование Groovy и рассматривается, когда и как его следует применять.

  • Groovy: Web-сайт проекта Groovy с дополнительной информацией.

  • AboutGroovy.com (EN): Web-сайт с последними новостями и ссылками на статьи о Groovy.

  • What's the secret sauce in Ruby on Rails? (Bruce Tate, developerWorks, май 2006 г.): в этой статье Брюса Тейта (Bruce Tate) из серии Crossing borders на страницах developerWorks рассказывается, почему Rails произвел такое впечатление.

  • HSQLDB и Jetty: База данных, написанная исключительно на Java, и сервлет-контейнер, поставляемые с Grails.

  • Model-View-Controller (EN): популярный шаблон проектирования, используемый в Grails.

  • Safari bookstore: сайт магазина книг по ИТ.(EN)

  • Раздел Технология Java сайта developerWorks: сотни статей обо всех аспектах Java-программирования.


Получить продукты и технологии

Обсудить


Об авторе

Скотт Дэвис (Scott Davis) является международно признанным автором, лектором и разработчиком программного обеспечения. Среди его книг: Groovy Recipes: Greasing the Wheels of Java, GIS for Web Developers: Adding Where to Your Application, The Google Maps API и JBoss At Work.




Выскажите мнение об этой странице


Пожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.



 


 


 


Поделиться этой статьей:

забобрить забобрить memori сохранить в memori




В начало


Java и все связанные с Java торговые марки принадлежат Sun Microsystems, Inc. в Соединенных Штатах Америки и других странах. IBM, логотип IBM, и WebSphere зарегистрированные торговые марки International Business Machines Corporation в Соединенных Штатах Америки и других странах. Названия других компаний, их продуктов или услуг могут быть торговыми марками других компаний. Другая компания, продукт или название услуги могут быть торговыми марками или знаками обслуживания, принадлежащими иным физическим или юридическим лицам.

IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.
    IBM в России Конфиденциальность Контакты