Pull to refresh

Grails — священный грааль веб-разработчика

Lumber room
grails

Вступление или муки выбора


Здравствуйте! Я хочу рассказать немного о Grails и показать, как создать простое веб-приложение. Начну с того, что я искал удобный и функциональный веб-фраймворк для быстрой разработки. Мой взгляд попеременно падал на Django, Ruby On Rails и различные разработки на Java. Безусловно, мне нравится Java, Spring Framework и Hibernate, всё вместе — это мощнейшая штука. Однако, некоторые моменты меня не устраивали:
  • Отставание языка Java по возможностям от других современных языков, а также ограничения в дизайне языка. Это выражается в отсутствии удобного способа написания бинов — создавать для каждого свойства свою пару геттеров и сеттеров несколько утомляет, отсутствует возможность использовать интуитивные математические операции над объектами (перегрузка операторов), нет поддержки функционального программирования, например, замыканий, нехватка синтаксического сахара, например, неудобство создания коллекции, заполненной конкретными значениями. Всё это и еще многое другое делает программы на Java несколько громоздкими и менее лаконичными, чем аналогичные, например, на Python;
  • Низкая скорость и сложность разработки веб-приложений — зачастую вместо написания кода работа сводится к настройке многочисленных конфигурационных файлов на XML, которые требуют дополнительного изучения.

Я стал искать альтернативу. PHP сразу отмёл в сторону ввиду несовершенности этого языка и традиций «велосипедостроения». Как любитель Python был опробован Django, который понравился своей простотой и удобством. Думаю, что делать небольшие проекты на Django в самый раз, но мне не понравился ограниченный функционал шаблонизатора, например отсутствие условий и присвоения переменных в шаблонах. Конечно, некоторые могут сказать, что в шаблоне должна быть минимальная логика — никаких переменных и ветвлений. Осмелюсь возразить, что по-моему мнению в реальных проектах это создает многочисленные неудобства. Правда, в новой версии Django, эти проблемы будут в скором времени решены. При всех плюсах этого фраймворка, мне не нравится его процедурная ориентированность — хотя это чисто субъективное мнение, а также процедурная ориентированность самого Python, как будто ООП появилось в нём только вчера, а также отсутствие средств защиты кода приложения на уровне самого языка программирования — в Pyhton нет констант, в классе все методы и свойства являются открытыми, и для того, чтобы сделать член класса приватным, приходится использовать подчеркивания, что делает код крайне неприятным в чтении. Смотрел на Ruby, как улучшенная версия Python с большим уклоном на ООП, но меня, как и многих, пробовавших Ruby, оттолкнул синтаксис и тормознутость интерпретатора, хотя в Ruby 1.9 дела обстоят куда лучше. Мне хотелось чего-то другого. И я нашел его — священный грааль.

Groovy — Java Next


Как любителя Java, я стал присматриваться к Groovy — языку нового поколения на основе Java. Он представляет из себя компилируемый язык программирования с приятным синтаксисом Java, простым в использовании и лаконичным, обладающий большой мощью. Программа на Groovy компилируется в байт-код виртуальной машины Java. К основным достоинствам относится совместимость с Java на уровне кода и библиотек, поддержка функционального программирования, море удобного синтаксического сахара, и ещё куча новых возможностей, которые сделают наш мир лучше:) Из Groovy можно использовать классы и библиотеки Java, так что весь накопленный опыт не останется за бортом. Из недостатков Groovy следует отметить динамическую типизацию этого языка — хотя типы переменных можно указывать явно, все проверки происходят на этапе исполнения кода, а не компиляции, вследствие чего мы имеем тормознутость по сравнению с Java, и как показали тесты — код на Groovy в среднем в 40 раз медленнее аналогичного Java-кода. Но у этой проблемы, думаю, в скором времени появится полноценное решение — совсем недавно появился Groovy++ — статический компилятор кода, который позволяет в одном проекте использовать как динамическую, так и статическую типизацию. Статическая типизация включается с помощью аннотации, и по результатам тестов код становится соизмеримым по скорости выполнения с «классическим» Java-кодом.

Священный грааль


Для тех, кто не знает, я говорю о Grails — веб-фраймворке для разработки веб-приложений на языке нового поколения — Groovy. Почему Grails? Grails вобрал лучшее из существующий технологий. Идеологией он похож на Ruby on rails и до каких-то пор он и назывался совсем похоже — Groovy on Rails, а потом был сокращен до привычного теперь «Grails». Grails представляет из себя надстройку над Spring, Hibernate с шаблонным движком Sitemesh и пользовательсими тэгами gsp. В отличие от Spring, где для создания простого приложения нужны дополнительные библиотеки, в Grails все включено «из коробки», не нужно настраивать никакие XML-конфигурации, и все манипуляции делаются простым и естественным способом. Сейчас Grails принадлежит лидеру разработки на Java — Spring Source. Для Grails существуют плагины, расширяющие его возможности, например acegi для работы с авторизацией и аутенфикацией. Grails следует принципу MVC, предлагает удобные средства для привязки URL к контроллерам, локализации приложения, валидации данных моделей и многое другое. Типичная структура проекта представляет из себя следующее:

%PROJECT_HOME%
	+ grails-app
		+ conf                   -> настройки
			+ hibernate
			+ spring
			BootStrap.groovy   -> загрузка приложения
			BuildConfig.groovy -> настройка сборки
			Config.groovy      -> общие настройки
			DataSource.groovy  -> настройки БД
			UrlMappings.groovy -> привязки URL к контроллерам
		+ controllers            -> контроллеры
		+ domain                 -> модели
		+ i18n                   -> локализация
		+ services               -> сервисы
		+ taglib                 -> пользовательские тэги
		+ utils                  -> вспомогательные классы
		+ views                  -> представления
			+ layouts          -> раскладки (контейнеры шаблонов)
	+ lib                          -> библиотеки
	+ plugins                      -> плагины для Grails
	+ scripts                      -> скрипты
	+ src
		+ groovy
		+ java
		+ main
	+ target
	+ test                         -> unit-тесты
	+ web-app
		+ WEB-INF

Итак, пришло время попробовать Grails.

Быстрый старт


Нам понадобятся следующие инструменты:
  • Java SDK 1.4 или выше
  • Grails
  • Maven
  • IDE для разработки. Я выбрал специальную сборку Eclipse от Spring Source

Скачиваем и распаковываем Grails (http://www.grails.org/Releases), устанавливаем переменную окружения GRAILS_HOME, которая указывает на полный путь к распакованному архиву, например ~/grails и добавляем GRAILS_HOME/bin в путь запуска. Скачиваем IDE по адресу www.grails.org/STS+Integration, устанавливаем и настраиваем так, как описано на сайте.

Теперь давайте создадим скелет нашего приложения testapp с помощью Maven:

$ mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:generate -DarchetypeGroupId=org.grails -DarchetypeArtifactId=grails-maven-archetype -DarchetypeVersion=1.2.0 -DgroupId=testapp -DartifactId=testapp

$ cd testapp
$ mvn initialize

Теперь запускаем Eclipse и делаем импорт нашего приложения. File -> Import -> Existing Projects into Workspace

После импорта вы увидите следующую структуру:

Структура проекта

Теперь давайте настроим наше приложение. Открываем файл grails-app/conf/DataSource.groovy и видим следующее содержимое:

dataSource {
	pooled = true
	driverClassName = "org.hsqldb.jdbcDriver"
	username = "sa"
	password = ""
}
hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
	development {
		dataSource {
			dbCreate = "create-drop" // one of 'create', 'create-drop','update'
			url = "jdbc:hsqldb:mem:devDB"
		}
	}
	test {
		dataSource {
			dbCreate = "update"
			url = "jdbc:hsqldb:mem:testDb"
		}
	}
	production {
		dataSource {
			dbCreate = "update"
			url = "jdbc:hsqldb:file:prodDb;shutdown=true"
		}
	}
}

dataSource содержит настройки соединения с базой данных. Приспособим их для работы с mysql:

dataSource {
	pooled = true
	driverClassName = "com.mysql.jdbc.Driver"
	username = "root"
	password = ""
}

Смотрим дальше, видим следующую секцию:

environments {
	development {
		dataSource {
			...
		}
	}

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

development {
	dataSource {
		dbCreate = "update"
		url = "jdbc:mysql://localhost:3306/testapp"
	}
}

Не забываем проверить, что сервис mysql у нас запущен, и база данных testapp создана.

Далее, открываем файл grails-app/conf/BuildConfig.groovy. Как я уже писал выше, это файл сборки приложения. Нас интересует следующий кусок кода:

repositories {        
        grailsPlugins()
        grailsHome()

        // uncomment the below to enable remote dependency resolution
        // from public Maven repositories
        //mavenLocal()
        //mavenCentral()
        //mavenRepo "http://snapshots.repository.codehaus.org"
        //mavenRepo "http://repository.codehaus.org"
        //mavenRepo "http://download.java.net/maven/2/"
        //mavenRepo "http://repository.jboss.com/maven2/"
    }
    dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

        // runtime 'mysql:mysql-connector-java:5.1.5'
    }

Это секция для устранения зависимостей при сборке. Исправляем так:

repositories {        
        grailsPlugins()
        grailsHome()

        // uncomment the below to enable remote dependency resolution
        // from public Maven repositories
        mavenLocal()
        mavenCentral()
        //mavenRepo "http://snapshots.repository.codehaus.org"
        mavenRepo "http://repository.codehaus.org"
        mavenRepo "http://download.java.net/maven/2/"
        //mavenRepo "http://repository.jboss.com/maven2/"
    }
    dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

        runtime 'mysql:mysql-connector-java:5.1.5'
    }

Мы добавили драйвер mysql. А теперь пришло время создать простое приложение. Для начала создадим модель Product, для этого нам нужно выполнить команду create-domain-class в консоли Grails. При создании моделей нам не нужно создавать вручную таблицу в базе данных, Grails сделает это сам. В Eclipse открываем: Navigate -> Open Grails Command Prompt и выполняем:

grails> create-domain-class com.testapp.Product

Процесс создания модели можно увидеть в консоли Eclipse. Если при создании вы увидели следующее сообщение:
Application expects grails version [1.2.0], but GRAILS_HOME is version [1.2.1] — use the correct Grails version or run 'grails upgrade' if this Grails version is newer than the version your application expects.

Это означает, что с помощью maven вы создали скелет приложения для grails 1.2.0, а у вас в системе стоит более новая версия. Следуйте инструкции и выполните команду upgrade:

grails> upgrade

Если процесс создания модели прошёл успешно, то в grails-app/domain/Product.groovy вы увидите следующий код:

package com.testapp

class Product {

    static constraints = {
    }
}

Заполним модель нужными нам полями — название товара, описание и цена:

class Product {

	String name
	String description
	Float price
	static constraints = {
		name(nullable: false, blank: false, size: 1..50)
		description(nullable: false, blank: false, size: 1..255)
	}
	
	String toString() {
		return name; 
	}
}

Замечательно! А теперь давайте создадим для нее CRUD. Для этого, нам не нужно писать контроллеры и представения, и мы можем обойтись одной командой, которая сгенерирует всё сама:

grails> generate-all com.testapp.Product

В результате мы видим:

Generating views for domain class com.testapp.Product…
Generating controller for domain class com.testapp.Product…
Finished generation for domain class com.testapp.Product

Этой командой были сгенерированы:
контроллер com.testapp.ProductController
отображения create.gsp, edit.gsp, list.gsp, show.gsp в каталоге grails-app/views/product

На этом наше простое приложение готово. Теперь можно запустить его c помощью команды run-app. Запущенное приложение будет доступно по адресу localhost:8080/testapp

image

image

image

image
Tags:
Hubs:
Total votes 23: ↑13 and ↓10 +3
Views 4.9K
Comments Comments 17