Kurs:Neueste Internet- und WWW-Technologien/Web-Entwicklung mit Grails

Aus Wikiversity



Grails ist ein Web Application Framework, das bewährte Java Technologien und die Fähigkeiten der dynamischen Programmiersprache Groovy nutzt. Dadurch ist Grails einfach, schnell und ohne komplexe Konfigurationen zu benutzen.

Grails - das Framework[Bearbeiten]

Grails ist ein web application framework für die Java Plattform, das stark von Ruby on Rails beeinflusst wurde[1]. Es unterstützt die Programmiersprachen Groovy und Java. Grails verfolgt das Convention over Configuration-Paradigma. Dieses schreibt bestimmte Konventionen, wie Klassennamen etc., vor. Dadurch macht es komplexe XML-Konfigurationen unnötig, solange keine Anpassungen benötigt werden. Außerdem bietet Grails Scaffolding-Funktionen an, die durch das automatische Erstellen von Views den Entwicklungsprozess beschleunigen und Debugging erleichtern. Groovy ermöglicht es Grails agil, und flexibel zu sein, und hilft bei der Einhaltung des Dont Repeat Yourself-Prinzips. Durch die Integration in die Java-Plattform können etablierte Java Technologien wie Spring oder Hibernate genutzt werden.

Aufbau und Architektur[Bearbeiten]

Ein Merkmal von Grails ist, dass nicht jede Funktionalität neu entwickelt wurde. Vielmehr baut Grails selbst auf anderen Frameworks auf. Dabei bietet es angepasste und einfachere Schnittstellen zu ihren Funktionalitäten (Beispiel: GORM). So stellt Grails mithilfe von Groovy eine zusätzliche Abstraktionsebene für diese Technologien dar, lässt aber gleichzeitig das Benutzen von deren Konfigurationsmöglichkeiten zu.[2]

Grails in der Version 2.0.3 baut auf folgenden Technologien auf:

  • Java EE: Die komponentenbasierte Enterprise Edition von Java ist eine Plattform für Unternehmenssoftware und erweitert die Java-Umgebung z.B. um API`s für verteilte Anwendungen oder Web-Services. Grails baut auf der Java-Servlet-API auf, die das Erweitern von Webserverfunktionalitäten und Bearbeiten von HTTP-Requests innerhalb eines Application-Servers oder Web-Containers ermöglicht.
  • Spring: bietet Inversion of Control und Runtime Dependency Injection Funktionalitäten
  • Hibernate: ist ein Object Relational Mapper (ORM) und wird von Grails z.B. durch GORM genutzt
  • SiteMesh: ein Layout-Rendering Framework


Außerdem stellt Grails eine komplette Entwicklungsumgebung für Web-Applikationen bereit. Dazu zählen:

  • ein integrierter Apache Tomcat-Container
  • eine H2 In Memory-Datenbank
  • Erweiterbarkeit durch Plug-ins

Geschichte[Bearbeiten]

Die Entwicklung von Grails begann im Jahr 2005. Ein Auslöser war das Erscheinen von Ruby on Rails. So wurde Grails in der Anfangszeit Groovy on Rails genannt, wurde aber 2006 auf Bitte des Ruby on Rails Erfinders David Heinemeier Hansson in Grails umbenannt. Seit 2008 ist Grails in der Version 1.0, und seit 2011 in der Version 2.0 vorhanden. Grails steht unter der Apache Lizenz, und wird von SpringSource, einem Tochterunternehmen von VMWare, weiterentwickelt.[3]

Groovy[Bearbeiten]

Groovy ist eine dynamisch typisierte Programmiersprache für die Java Virtual Machine (JVM). Die Syntax von Groovy lehnt sich dabei stark an Java an. Dadurch ist es besonders für Java-Entwickler leicht zu erlernen. Groovy erweitert Java aber um Konzepte aus Sprachen wie Smalltalk, Python oder Ruby. Zu diesen Konzepten gehören vor allem die native Unterstützung von Closures und Collections. Obwohl Groovy eine dynamische Sprache ist, ermöglicht sie auch gleichzeitig statisch getypte Variablen und statische Typprüfung. Ein großer Vorteil von Groovy ist, dass es sich nahtlos in bestehende Java-Umgebungen einsetzen und auch mit Java kombinieren lässt. Dies wird möglich, da Groovy keine interpretierte Sprache ist, sondern direkt zu JVM-Bytecode kompiliert wird.[4][5]

Überblick[Bearbeiten]

Die Syntax von Groovy ist stark an die Java Syntax angelehnt. Zu den Gemeinsamkeiten zählen:

  • Schlüsselwörter (z.B. class oder return)
  • Klassen- und Methodendefinitionen
  • Kontrollflußoperatoren
  • Kommentare

Beispiel für eine Klassendefinition in Groovy:

 class Hello{
	def world = "Hello World"
	int typed = 1
}

Die Klasse Hello besitzt eine dynamisch typisierte Property "world", welche durch das Schlüsselword def definiert wird, und eine statisch getypte Variable "typed".

Weitere Eigenschaften von Groovy:

  • echte Objektorientierung mit autoboxing/unboxing
  • das optionale Setzen von Semikolons am Anweisungsende bei eindeutigem Code
  • automatisches Importieren von java.lang.*, java.io.*, java.util.*, java.net.*, groovy.lang.* ,groovy.util.*
  • Assertions auf Sprachebene
  • Unterstützung von Domain Specific Languages für leichter lesbaren Code
  • Metaprogrammierung und Reflection.[6]

Java Bytecode Kompatibilität[Bearbeiten]

Groovy-Code wird direkt zu JVM-Bytecode kompiliert. Dadurch ist eine kompilierte Groovy-Klasse auch eine kompilierte Java-Klasse und umgekehrt. Das ermöglicht das Interoperieren von Groovy und Java auf Bytecode-Ebene. So ist es zum Beispiel möglich direkt aus Groovy heraus ein Interface, welches von Java implementiert wird, aufzurufen.

def world = {render "Hello World it's "+ java.util.Date()}

Dieses Feature ermöglicht es Groovy bestehende Java-Technologien und -Werkzeuge zu integrieren und auch auf zukünftige Entwicklungen vorbereitet zu sein.[7]

Groovy Strings[Bearbeiten]

Groovy besitzt zwei Arten von String-Typen: Strings und Groovy Strings (GStrings). Normale Strings sind vergleichbar mit der Java String-Klasse. GStrings werden durch doppelte Anführungszeichen deklariert. Sie erlauben das Einbetten von beliebigen Groovy-Ausdrücken, wobei diese bei der Anwendung des GStrings ausgewertet und in den GString eingefügt werden. Ein weiteres Feature von GStrings ist, dass diese mehrzeilig sein können. So kann mit """ ein mehrzeiliger GString deklariert werden, in dem z.B. HTML-Code ohne Kodierung direkt eingebettet sein kann.[8]

Im folgenden Beispiel wird die Nutzung von GStrings dargestellt:

def person = "John“;
println """
${new Date()}

Dear $person,
This is a Groovy letter!

Yours Sincerely,
XYZ
"""

In der ersten Zeile des Beispiels wird eine Variable mit dem Namen "person" angelegt. Diese kann im GString direkt mit $person eingesetzt werden, ohne aufwendige Stringkonkatenationen durchführen zu müssen. Innerhalb von ${ } können beliebige Groovy-Ausdrücke stehen. In diesem Fall wird ein neues Date-Objekt erzeugt. Wenn der GString aufgerufen wird, dann wird dieser Ausdruck ausgewertet und auf das Datumsobjekt wird die toString-Methode aufgerufen, sodass das Datum an dieser Stelle in den String integriert wird.

Closures[Bearbeiten]

Closures sind anonyme Code-Blöcke, die an einer Stelle im Code definiert werden und dann an mehreren Stellen wiederholt ausgeführt werden können.[9]

Beispiel - Anwendung von Closures mit Parametern:

def printSum = { a, b -> print a+b }
printSum( 5, 7 ) //prints "12”

Hier wird innerhalb der geschweiften Klammern eine Closure definiert. Vor dem optionalen -> können dabei Parameter definiert werden. Die Closure wird an die Property "printSum" zugewiesen, und mit printSum(5,7) mit den Argumenten 5 und 7 ausgeführt.

Beispiel - Closure mit freier Variable:

def myConst = 5
def incByConst = { num -> num + myConst }
println incByConst(10) // => 15

In diesem Beispiel enthält die Closure eine Variable die nicht in der Parameterliste definiert wird. Diese Variable wird als frei bezeichnet und an eine Variable im Scope der Closure-Definition gebunden.

Beispiel - Closure mit impliziter Variable "it":

def clos = { print it }
clos( "hi there" ) //prints "hi there"

Wenn in einer Closure-Definition keine Parameter definiert werden, erhält die Closure immer einen impliziten Parameter it.

Collections[Bearbeiten]

Groovy bietet native Unterstützung für verschiedene Typen von Collections wie Listen, Maps, oder Ranges.[10]

Beispiel - Definition von Collection-Typen:

def list = [5, 6, 7, 8]
def range = 5..8	// java.util.list
def map = [name:"Gromit", likes:"cheese", id:1234]

Objekte vom Typ Range werden intern als java.util.list gespeichert. Eine Map ist eine Liste von Schlüssel-Wert-Paaren, wobei der Wert in Anführungszeichen nach dem Schlüssel steht.

Beispiel - Zusammenspiel von Collections und Closures:

def words = ['ant', 'buffalo', 'cat', 'dinosaur']
assert words.findAll{ w -> w.size() > 4 } == ['buffalo', 'dinosaur']

Hierbei wird eine Liste "words" definiert, auf der dann die findAll()-Methode mit einer Closure als Parameter ausgeführt wird. Die Closure wird dabei auf jedes Objekt der Liste wie ein Filter angewendet. Das Ergebnis ist eine neue Liste, wobei nur Objekte die die Bedingung in der Closure erfüllen vertreten sind.

Webentwicklung mit Grails[Bearbeiten]

Grails ist ein MVC Framework. Das bedeutet, dass die Daten der Anwendung (Model), die Darstellung der Daten (View) und die Steuerung von Benutzereingaben (Controller) wie in der nachfolgenden Abbildung voneinander getrennt werden.

Abbildung: Model-View-Controller Schema

Grails unterstützt zusätzlich das Konzept von Services, um die Geschäftslogik einer Anwendung von der Controller-Logik zu trennen.
Dieses Kapitel erläutert beispielhaft an der Entwicklung einer Bookmarks Web-Anwendung die Entwicklung mit Grails[11].

Entwicklungsumgebung[Bearbeiten]

Grails ist nicht nur ein Framework, sondern auch eine komplette Entwicklungsumgebung. Sie bringt einen interaktiven Kommandozeilen-Modus mit Build-System, einen startfertigen Tomcat-Container, sowie eine H2 In-Memory-Datenbank mit. Die springsource toolsuite (STS) ermöglicht zudem eine einfache Eclipse-Integration der Grails Entwicklungsumgebung. Die offizielle Grails Dokumentation bietet einen Installations-Guide, um Grails auf dem eigenen System zu installieren.[12] Sobald Grails installiert ist, kann ein neues Projekt angelegt werden:

grails create-app bookmarks
Grails interaktiver Modus

Dadurch legt Grails ein Verzeichnis, wie in der folgenden Abbildung zu sehen, an.


Abbildung: Die von Grails angelegte Ordnerstruktur

Um eine Anwendung im interaktiven Modus zu starten bietet Grails folgendes Kommando:

run-app

Domänen-Modellierung[Bearbeiten]

Durch das Model werden die zentralen Entitäten der Domäne innerhalb der Anwendung definiert. In Grails sind dies Groovy-Klassen, die mit folgendem Befehl im grails-app/domain-Verzeichnis angelegt werden:

grails create-domain-class Bookmark

Diese Domänen-Klassen müssen kein spezielles Interface implementieren oder von einer bestimmten Klasse abgeleitet werden. Die Verbindung zum Framework geschieht durch Konvention (das domain-Verzeichnis), und "Runtime-Injection".[13] Um die Domänen Klassen zu persistieren wird GORM genutzt.

Die User-Klasse der Bookmarks Web-Application:

class User {

	static hasMany = [bookmarks: Bookmark]
	
	String login
	String password
	String name
	String email
	
	static constraints = {
		login( unique: true, length:5..15 )
		password( matches:/[\w\d]+/, length:6..12)
		email( email:true)
		name( blank:false)
    }
}


Die Bookmark-Klasse der Bookmarks Web-Application:

class Bookmark {

  	static belongsTo = User
	
	String url
	String title
	Date dateCreated
}

GORM[Bearbeiten]

Grails Object Relational Mapping (GORM) erlaubt eine sehr einfache Objektrelationale Abbildung auf eine Datenbank. GORM basiert auf Hibernate. Anstatt jedoch die Abbildung von Objekten auf eine Relationale Datenbank in XML-Dateien zu deklarieren, geschieht dies in Grails allein durch die Konventionen in den Klassen. Dadurch muss der Anwender nur die Konventionen befolgen. Den Rest übernimmt GORM automatisch. Die Abbildung von Klassen und deren Properties auf die Datenbank geschieht nach folgendem Schema:


Dabei wird für jede Property eine Spalte angelegt, außerdem erhält jedes Objekt dieser Klasse einen Identifier.[14]

CRUD[Bearbeiten]

Create, Read, Update und Delete sind die fundamentalen Aktionen jeder auf einer Datenbank beruhenden Anwendung.

Create:

def b = new Bookmark(url: new URL('http://www.hpi-web.de'), title: 'HPI', notes: '...')
b.save()

Ein Domänenobjekt wird über den new-Operator erzeugt und durch den Aufruf der save-Methode persistiert.

Read:

def b = Bookmark.get(1)

Hierbei wird mithilfe der Klassenmethode "get" und der "id" des Objekts die Bookmark Tabelle nach dem passenden Objekt durchsucht. Im Fehlerfall wird null zurückgegeben.

Update:

def b = Bookmark.get(1)
b.notes = 'Hasso Plattner Institut'
b.save()

Um ein bestehendes Domänenobjekt zu verändern wird zuerst das Objekt gelesen, dann verändert und schließlich wieder mit save() gespeichert.

Delete:

def b = Bookmark.get(1)
b.delete()

Um ein Objekt aus der Datenbank zu löschen wird die delete-Methode des Objekts aufgerufen.

Relationships[Bearbeiten]

Um zwischen Domänenklassen Relationships zu definieren bietet Grails eine besondere Notation an. In diesem Beispiel soll ein User-Objekt über mehrere Bookmark-Objekte verfügen.

Abbildung: Beziehung zwischen den Klassen User und Bookmark

Um diese bidirektionale Beziehung auf die Domänen-Klassen abzubilden wird folgender Code benötigt:

// class User
static hasMany = [bookmarks: Bookmark]

//class Bookmark
static belongsTo = User

Die static Property "hasMany", der eine Map-Collection zugewiesen wird, definiert eine 1:n Beziehung zwischen den beiden Klassen. Dabei legt GORM automatisch eine java.util.Set Property mit dem Schlüssel der Map in der Klasse User an. Durch die belongsTo-Property in der Klasse Bookmark wird die User-Klasse als Besitzer der Bookmark-Klasse definiert. Das hat zur Folge, dass Save- und Delete-Operationen von einem User-Objekt zum Bookmark-Objekt kaskadieren, aber nicht anders herum.
Grails erlaubt ebenfalls das Aufstellen von n:m-Beziehungen (mit hasMany-Properties auf beiden Seiten) oder 1:1-Beziehungen (mit einer hasOne-Property).[15]

Constraints[Bearbeiten]

Bevor ein Domänenobjekt in der Datenbank persistiert wird, kann es mit sogenannten Constraints validiert werden. Beim Aufrufen von save() auf einem Objekt, wird automatisch in den Constraints der Klasse überprüft, ob es gespeichert werden darf. Constraints werden direkt in der "constraints"-Property einer Klasse definiert. Dazu stellt Grails eine deklarative Domain Specific Language (DSL) bereit.[16]

//class User
static constraints = {
                login( unique: true, length:5..15 )
                password( matches:/[\w\d]+/, length:6..12)
                email( email:true)
                name( blank:false)
    }

In diesem Beispiel wird, bevor ein User Objekt gespeichert überprüft, ob der Login noch nicht vergeben und zwischen 5 und 15 Zeichen lang ist, ob das Passwort aus 6 bis 12 alphanumerischen Zeichen besteht, ob die E-Mail Adresse ein entsprechendes Format hat und ein Name eingegeben wurde.

Anfragen an das Model[Bearbeiten]

Im Abschnitt CRUD wurde bereits die statische get-Methode vorgestellt. Allerdings bietet Grails noch wesentlich ausgefeiltere Methoden an, um bestimmte Domänenobjekte aus der Datenbank auszulesen. Ein Beispiel dafür sind die sogenannten dynamic finders. Diese Methoden sind von Grails dynamisch erstellt, und benutzen die Namen der Properties einer Klasse um Anfragen zu bilden. Durch das Ermöglichen von AND, OR oder NOT können damit method expressions (Ausdrücke in Methodennamen) erstellt werden, wodurch dynamic finders sehr flexibel sind.[17]

Bookmark.findByTitleAndUrl('HPI',new URL('http://www.hpi-web.de'))

In diesem Beispiel wird eine sogenannte findBy* Methode der Klasse Bookmark ausgeführt, wobei der Stern mit einer method expression ersetzt wird. Es wird nach Bookmark-Objekten gesucht, deren Titel HPI und deren URL hpi-web.de ist. Es existieren viele weitere Möglichkeiten mit denen dynamic finder-Methoden gebildet werden können:

Bookmark.findAllByTitleLike('H%') // findet alle Objekte deren Titel mit H beginnen, und gibt eine Liste zurück
Bookmark.findAllByCreatedBetween(new Date(), new Date() - 10) // findet alle Objekte die in den letzten 10 Tagen erstellt wurden

Da Grails auf Hibernate aufbaut ist es auch möglich Anfragen alternativ in der Hibernate Query Language (HQL) auszuführen.

Controller[Bearbeiten]

Die Aufgabe eines Controllers ist es, Nutzeranfragen an die Anwendung entgegenzunehmen und weiterzuleiten, sowie Antworten an den Nutzer zu bearbeiten. Wenn ein Controller eine Nutzeranfrage (Request) erhält, z.B. über HTTP, dann kann der Controller folgendes tun[18]:

  • die Anfrage an eine entsprechende View, die angezeigt werden soll, weitergeleiten
  • aus dem Domänenmodell/Datenbank Daten extrahieren, und an eine View zur Darstellung weitergereichen
  • direkt eine Antwort formulieren
  • zu einem anderen Controller (oder Action) weiterleiten

Controller sind Groovy-Klassen, die per Konvention im grails-app/controllers-Ordner liegen, und deren Name mit Controller endet. Sie umfassen mehrere Actions. Das sind Closure-Properties die bestimmte Aktionen eines Controllers, wie z.B. alle Bookmarks anzeigen oder eine Bookmark löschen, definieren. Grails schreibt ein standardmäßiges URL-Mapping, eine Zuordnung über welche Anfragen anhand der URL an einen Controller weitergereicht werden, vor. Dieses kann jedoch über ein Plugin angepasst werden.

Standard URL-Mapping:

http://localhost:8080/application/controller/action


Um einen Controller anzulegen bietet Grails den folgenden Befehl:

grails create-controller Bookmark


Wenn ein Controller eine Action "index" besitzt, so ist dies nach Konvention seine standardmäßige Action. Sie wird aufgerufen, wenn der Controller aufgerufen wird. Zu jeder Action eines Controllers existiert in der Regel eine View. Wenn die Action aufgerufen wird und über return eine Map zurückgibt, wird die Map (auch model genannt) an die entsprechende View weitergeleitet. Um zu einem anderen Controller oder einer anderen Action umzuleiten existiert der redirect-Befehl, dem man die Namen des entsprechenden Controllers bzw. der Action als Parameter mitgibt. Mithilfe des render-Befehls kann ein Controller auch selbst eine Antwort erstellen, ohne eine View anzuzeigen.

Grails baut auf der Java Servlet API auf. Diese definiert bestimmte Objekte, wie z.B. HttpServletRequest, welche die Schnittstellen zwischen dem Servlet Container und der darin laufenden Anwendung definieren. Dadurch bietet sie der Anwendung Zugriff auf Kommunikationsparameter. In Grails stehen bestimmte Objekte bereit, die auf der Servlet API aufbauen und auf die innerhalb von Controllern zugegriffen werden kann:[19]

  • request: Dieses Objekte ist eine Instanz der HttpServletRequest Klasse, und bietet Informationen über die Anfrage des Nutzers.
  • response: Dieses Objekt der Klasse HttpServletResponse ermöglicht das Zusammenstellen von Antworten. Zum Beispiel können Binärdaten oder Fehlercodes so direkt in die Response geschrieben werden.
  • params: Dies ist eine Map mit Anfrageparametern (CGI).
  • session: Ein Objekt der Klasse HttpSession. Es dient zur Speicherung von Session-Daten eines Clients.

Beispiel - BookmarkController:

class BookmarkController {

    // default index action
	def index = { 
		def tempBookmarks = []
		Bookmark.getAll().each { tempBookmarks += [[id: it.id, url:it.url, title:it.title, dateCreated: it.dateCreated]] }
		return [bookmarks:tempBookmarks] // model that is returned to view index.gsp
	}
	
	
	def create = { } // only calls create view
	
	
	def submit = {
		def user = User.findByLogin(params.user) //dynamic finder method  findBy*
		
		if (user == null)
			redirect(controller:'user')
		else
		{
			Bookmark bookmark = new Bookmark(url:params.url, dateCreated:new Date(), title:params.title)
			bookmark.save()
			redirect(action:'index')
		}
	}
	
	
	def delete = {
		def bookmark = Bookmark.get(params.id)
		bookmark.delete()
		redirect(action:'index')
	}
	
}


Scaffolding[Bearbeiten]

Scaffolding ist ein Feature von Grails, das es erlaubt für eine Domänenklasse automatisch Views und CRUD-Operationen zu erzeugen. Dies beschleunigt den Entwicklungsprozess, da es Debugging von Domänenklassen ermöglicht, ohne Controller oder Views zu schreiben. Um Scaffolding für eine Domänenklasse zu aktivieren wird ein leerer Controller erstellt, der eine statische "scaffold" Property besitzt.

class UserController {

    static scaffold = true
}

Dadurch werden folgende Actions und dazugehörige Views erstellt: list, show, edit, delete, create, save, update.

Durch Scaffolding erstellte View









Views[Bearbeiten]

Views haben die Aufgabe Daten für den Nutzer darzustellen. Die View-Technologie von Grails nennst sich Groovy Server Pages (GSP) und setzt auf Java Server Pages (JSP) auf. Wenn in einem Controller eine Map (model) mit return zurückgegeben wird, dann wird diese an eine View weitergeleitet. Die View befindet sich nach Konvention im Verzeichnis grails-app/views/controller/action.gsp des jeweiligen Controllers bzw. der jeweiligen Action. Sie kann dann auf dieses model, sowie auf die Objekte params, request, response, session etc. zugreifen.
Groovy Server Pages sind eine Mischung aus Markup-Code (HTML, XML) und GSP-Tags. GSP erlaubt das Einbinden von GString Ausdrücken. So können wie in GStrings auch innerhalb von ${ } beliebige Groovy-Ausdrücke stehen. GSP-Tags sind Grails-eigene XML-Tags die mit einem g: beginnen. GSP-Tags bieten eine Reihe von Funktionen zum Aufbau von Seiten an:[20]

Logische Tags:

<g:if test="${ Bedingung }"> ... </g:if>

Das GSP if-Tag enthält ein Attribut test mit einem Ausdruck. Wenn dieser Ausdruck zu True ausgewertet ist, wird auch der Markup-Code im if-Tag angezeigt.

Iterative Tags:

<g:each in="${bookmarks}" var="bookmark"> ... </g:each>

Hierbei wird in einer Schleife über alle Elemente der Collection bookmarks iteriert, also der innere Markup-Code angezeigt. Innerhalb des each-Tags kann mit der Variable bookmark auf das aktuelle Element der Iteration zugegriffen werden. Die Collection bookmark muss in diesem Fall von einer Action als model an die View weitergereicht werden.

Link-Tags:

<g:link controller="user" action="index">users</g:link>

Mit einem Link-Tag wird ein Hyperlink erstellt, der auf die in den Attributen angegebene Action oder den Controller verweist.

Form-Tags:

<g:form action="submit">...</g:form>

Mit Form-Tags können HTML-Forms erstellt werden. Dies hat den Vorteil, dass die Daten sehr einfach an einen bestimmten Controller oder eine Action übergeben werden können. Dazu spezifiziert man als Attribut den entsprechenden Controller bzw. die Action.


Beispiel - Bookmark/index.gsp:

<html>
<head>
<title>bookmarks</title>
</head>
	<body>
		<h2>bookmarks</h2>
		<g:if test="${bookmarks.empty}">there are no bookmarks</g:if>
		<g:each in="${bookmarks}" var="bookmark">
			<p>goto: <a href="http://${bookmark.url}">${bookmark.title}</a>,
			<g:link action="delete" params="${[id:bookmark.id]}">delete link</g:link></p>
		</g:each>
		
		<p><g:link controller="user">users</g:link></p>
		<p><g:link action="create">create new bookmark</g:link></p>
	</body>
</html>

Beispiel - Bookmark/create.gsp:

<html><head>
<title>create a bookmark</title>
</head>
	<body>
		<h1>create a bookmark</h1>
		<g:form action="submit">
			title: <g:textField name="title" /> <br />
			url: <g:textArea name="url" /> <br />
			user: <g:textField name="user" /> <br />
			<g:submitButton name="submit" value="ok" />
			<g:actionSubmit action="index" value="cancel" />
		</g:form>
	</body>
</html>
</html>

Deployment[Bearbeiten]

Um eine fertige Grails Web-Application auf einem Web-Container oder Servlet-Container wie dem Apache Tomcat zu installieren, muss die Applikation zuerst in ein Web Application Archive (WAR) exportiert werden. Dazu existiert das Grails Kommando "war". Danach kann die resultierende war-Datei einfach im Container platziert werden.[21]

Beispiele: Grails im Einsatz[Bearbeiten]

Unter anderem wird Grails auf diesen Seiten eingesetzt:
Nissan USA
Parksystem Berliner Flughäfen
Tv-Sender Sky
Weitere Beispiele von Grails im Einsatz lassen sich auf der offiziellen Grails-Seite finden.

Diskussion[Bearbeiten]

Die Stärken von Grails liegen vor allem darin, dass es sich sehr gut in bestehende Java-Umgebungen integrieren lässt und bewährte Technologien wie Hibernate, Spring oder Java EE integriert werden. Durch den Convention over Configuration- und Don't Repeat Yourself-Ansatz wird die Produktivität in der Entwicklung von Java Web-Anwendungen teils erheblich gesteigert. Die Wahl der Sprache Groovy als Grundlage trägt dazu in besonderem Maße bei. Doch auch Grails ist nicht frei von Nachteilen. So ist die Grails-Magie für Anfänger teilweise nicht leicht zu durchschauen und auch Convention over Configuration erfordert Anwenderwissen.

Literatur[Bearbeiten]

[Rocher 2006] Rocher G.: The Definitive Guide to Grails, Apress, Berkeley 2006, 1-59059-758-3
[SmithLedbrook2009] Smith G.; Ledbrook P.: Grails in Action, Manning, Greenwich 2009, 978-1-933988-93-1
[RocherBrown2009] Rocher G., Brown J.: The Definitive Guide to Grails (Second Edition), Apress, Berkeley 2009, 978-1-59059-995-2

Einzelnachweise[Bearbeiten]

  1. [SmithLedbrook2009] S. 4
  2. [Rocher2006] S. 5-6
  3. http://de.wikipedia.org/wiki/Grails abgerufen am 22.07.2012
  4. http://groovy.codehaus.org/ abgerufen am 22.07.2012
  5. [Rocher2006] S. 5
  6. [Rocher2006] S. 18 ff
  7. [RocherBrown2009] - S.4
  8. http://groovy.codehaus.org/Strings+and+GString abgerufen am 22.07.2012
  9. http://groovy.codehaus.org/Closures abgerufen am 22.07.2012
  10. http://groovy.codehaus.org/Collections abgerufen am 22.07.2012
  11. vgl. [Rocher2006]
  12. http://grails.org/doc/latest/guide/introduction.html#developmentEnvironmentFeatures abgerufen am 22.07.2012
  13. [Rocher2006] S. 63
  14. [Rocher2006] S. 64
  15. http://grails.org/doc/latest/guide/GORM.html#gormAssociation abgerufen am 22.07.2012
  16. [Rocher2006] S. 82
  17. [Rocher2006] S. 71
  18. [Rocher2006] S. 139 ff.
  19. [Rocher2006] S. 142
  20. http://grails.org/doc/latest/guide/theWebLayer.html#gsp abgerufen am 22.07.2012
  21. http://grails.org/Deployment/ abgerufen am 22.07.2012

Weiterführende Links[Bearbeiten]

offizielle Grails Seite
offizielle Grails Dokumentation - Quick Start
offizielle Groovy Seite