<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>all-IT &#187; Grails</title>
	<atom:link href="http://www.k-oo.de/blog/category/grails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.k-oo.de/blog</link>
	<description>all-IT ist ein Blog aus dem IT Alltag</description>
	<lastBuildDate>Fri, 03 Feb 2012 09:42:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Upgrade auf Grails 2.0</title>
		<link>http://www.k-oo.de/blog/2012/02/03/upgrade-auf-grails-2-0/</link>
		<comments>http://www.k-oo.de/blog/2012/02/03/upgrade-auf-grails-2-0/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 09:42:21 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=2525</guid>
		<description><![CDATA[Mein favorisiertes Web-Framework Grails hat die Major Version 2 erreicht. Bei der Fülle an neuen Funktionen ist die 2 vor dem Punkt mehr als gerechtfertigt. Einen guten Überblick, über das was sich geändert hat, bietet der Artikel &#8220;Das ist neu in Grails 2.0&#8221; von Dierk König. Für mich war schon die neue interaktive Grails Console [...]]]></description>
			<content:encoded><![CDATA[<p>Mein favorisiertes Web-Framework Grails hat die Major Version 2 erreicht. Bei der Fülle an neuen Funktionen ist die 2 vor dem Punkt mehr als gerechtfertigt. Einen guten Überblick, über das was sich geändert hat, bietet der Artikel &#8220;<a href="http://it-republik.de/jaxenter/artikel/Das-ist-neu-in-Grails-2.0-4272.html" title="Artikel: Das ist neu in Grails 2.0" target="_blank">Das ist neu in Grails 2.0</a>&#8221; von Dierk König. </p>
<p>Für mich war schon die neue interaktive Grails Console mit TAB- Vervollständigung, farbiger, einzeiliger Ausgabe und formatierten Fehlerausgaben das Upgrade wert. Sie ist vor allem bei der Befehlsausführung sehr viel schneller, da dafür keine eigene JVM gestartet werden muss.<br />
Als Testkandidat musste meine Beispiel Grails Anwendung <a href="http://code.google.com/p/grum/" title="Grails Beispiel Anwendung grum" target="_blank"><strong>grum</strong></a> (sourcecode auf <a href="http://code.google.com/p/grum/" title="Grum Sourcecode" target="_blank">Google Code</a>) herhalten. Doch so einfach wie ein upgrade von einer Minor Version auf eine andere war es nicht. </p>
<p>Als erstes sollte man die <a href="http://grails.org/doc/latest/guide/gettingStarted.html#upgradingFromPreviousVersionsOfGrails" title="upgrade Hinweise" target="_blank">upgrade Hinweise</a> verinnerlichen, denn ein einfaches <code>grails upgrade</code> führte bei mir erst einmal zu einem inkonsistentem Projekt in meiner Entwicklungsumgebung (<a href="http://www.springsource.com/developer/sts" title="Eclipse basierte Entwicklungsumgebung mit sehr gutem Grails Support" target="_blank">SpringSource Tool Suite</a>).</p>
<p>Schuld ist man meistens selbst. Doch wo liegen nun die Fallstricke?</p>
<h3>Dependency Management</h3>
<p>Ein Thema, was ich bis jetzt vollständig ignoriert hatte, war das Dependency Management. In den vorherigen Grails Versionen lagen alle benötigten Bibliotheken (wie der JDBC Treiber) im <code>lib</code> Verzeichnis. Sauberer ist es natürlich die Abhängigkeiten zu deklarieren. Bei Grails macht man dies in der BuildConfig Klasse.</p>
<p><strong>conf/BuildConfig.groovy</strong></p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">dependencies <span style="color: #66cc66;">&#123;</span>
   <span style="color: #808080; font-style: italic;">// specify dependencies here under either </span>
   <span style="color: #808080; font-style: italic;">//'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.</span>
&nbsp;
   runtime <span style="color: #ff0000;">'mysql:mysql-connector-java:5.1.16'</span>
   build <span style="color: #ff0000;">&quot;displaytag:displaytag:1.2&quot;</span>
   runtime <span style="color: #ff0000;">&quot;displaytag:displaytag-export-poi:1.2&quot;</span>
   runtime <span style="color: #ff0000;">&quot;displaytag:itext:1.3&quot;</span>
   runtime <span style="color: #ff0000;">&quot;displaytag:poi:3.2&quot;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Danach sollte man in der IDE die Abhängigkeiten über <strong>Grails Tools -> Refresh Dependencies</strong> aktualisieren. Reicht dies nicht aus (wie bei mir) hilft es das Dependency Management zu stoppen und zu starten.</p>
<ul>
<li>Grails Tools -> Disable Dependency Management</li>
<li>Grails Tools -> Enable Dependency Management</li>
</ul>
<p>Alternativ kann man in der Grails Konsole folgende Befehle absetzen:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">grails<span style="color: #000000; font-weight: bold;">&gt;</span> clean
grails<span style="color: #000000; font-weight: bold;">&gt;</span> war</pre></div></div>

<h3>Plugins</h3>
<p>Dabei kam es bei mir zu Kompilierungs Problemen im Zusammenhang mit den automatisch installierten Plugins <strong>jquery</strong> und <strong>resources</strong>, was ich nur durch eine Neuinstallation der Plugins beheben konnte</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">grails<span style="color: #000000; font-weight: bold;">&gt;</span> uninstall-plugin <span style="color: #000000; font-weight: bold;">&lt;</span>plugin-name<span style="color: #000000; font-weight: bold;">&gt;</span>
grails<span style="color: #000000; font-weight: bold;">&gt;</span> install-plugin <span style="color: #000000; font-weight: bold;">&lt;</span>plugin-name<span style="color: #000000; font-weight: bold;">&gt;</span></pre></div></div>

<h3>TagLibs</h3>
<p>Und wo man schon mal beim Aufräumen ist. Das Tag <strong>createLinkTo</strong> ist <em>depracted</em> und sollte durch das Tag <strong>resources</strong> ersetzt werden. An dieser Stelle sollte man auch auf folgenden upgrade Hinweis achten:</p>
<blockquote><p>
If you install Resources (or it is installed automatically), tags like &lt;g:javascript&gt; won&#8217;t write anything to the page until you add the &lt;r:layoutResources/&gt; tags to your layout.
</p></blockquote>
<h3>Content Negotiation</h3>
<p>Ein Punkt warum ich Grails so mag ist, das sich damit sehr leicht REST APIs umsetzen lassen. Hier hat sich in der Version 2.0 auch etwas geändert. Die <a href="http://de.wikipedia.org/wiki/Content_Negotiation" title="Wikipedia Artikel: Content Negotiation" target="_blank">Content Negotiation</a> richtet sich jetzt nicht mehr nach dem akzeptierten Format des Responses, sondern nach dem Content-Type des Requests.<br />
Dafür muss man im Code <strong>withFormat</strong> durch <strong>request.withFormat</strong> ersetzen. Testen kann man diese Änderung mit <code>curl</code>. Z.B. mit:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">curl <span style="color: #660033;">--header</span> Content-Type:text<span style="color: #000000; font-weight: bold;">/</span>xml http:<span style="color: #000000; font-weight: bold;">//</span>localhost:<span style="color: #000000;">8080</span><span style="color: #000000; font-weight: bold;">/</span>grum<span style="color: #000000; font-weight: bold;">/</span>contactData<span style="color: #000000; font-weight: bold;">/</span>list</pre></div></div>

<p><strong>Fazit:</strong><br />
Das Upgrade lohnt sich, auch wenn es mit etwas mehr Arbeit verbunden ist, als sonst.</p>
<p><strong>Links:</strong><br />
<a href="http://code.google.com/p/grum/" title="grum project auf Google Code" target="_blank">grum</a> &#8211; Grails 2.0 Beispiel Applikation</p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=2525&amp;md5=7f15ba7267bd61a327e46d2f422de8d4" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2012/02/03/upgrade-auf-grails-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=2525&amp;md5=7f15ba7267bd61a327e46d2f422de8d4" type="text/html" />
	</item>
		<item>
		<title>Video &#8211; Tutorials für Grails</title>
		<link>http://www.k-oo.de/blog/2011/03/18/video-tutorials-fur-grails/</link>
		<comments>http://www.k-oo.de/blog/2011/03/18/video-tutorials-fur-grails/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 09:46:13 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=2254</guid>
		<description><![CDATA[Video &#8211; Tutorials sind neben einem Fachbuch ein guter Einstieg in ein Thema. Von Springsource gibt es zum Thema Grails zwei sehenswerte Tutorials auf youtube. Wenn Ihr Euch für das Webframework Grails interessiert, solltet Ihr Euch eine halbe Stunde für diese zwei gut gemachten Videoanleitungen nehmen. via: Neues Video-Tutorial zu Grails &#8211; it-republik.de]]></description>
			<content:encoded><![CDATA[<p>Video &#8211; Tutorials sind neben einem Fachbuch ein guter Einstieg in ein Thema. Von <a href="http://www.springsource.com/">Springsource</a> gibt es zum Thema <a href="http://www.grails.org">Grails</a> zwei sehenswerte Tutorials auf <a href="http://www.youtube.com">youtube</a>.<br />
Wenn Ihr Euch für das Webframework Grails interessiert, solltet Ihr Euch eine halbe Stunde für diese zwei gut gemachten Videoanleitungen nehmen.</p>
<p><iframe title="YouTube video player" width="500" height="304" src="http://www.youtube.com/embed/PXHxo43hn34" frameborder="0" allowfullscreen></iframe></p>
<p><iframe title="YouTube video player" width="500" height="304" src="http://www.youtube.com/embed/qNFksvLxZNU" frameborder="0" allowfullscreen></iframe></p>
<p><strong>via:</strong><br />
<a href="http://it-republik.de/jaxenter/news/Neues-Video-Tutorial-zu-Grails-058587.html">Neues Video-Tutorial zu Grails</a> &#8211; it-republik.de</p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=2254&amp;md5=84788c8541ef1b89b87b1ab7bff19abf" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2011/03/18/video-tutorials-fur-grails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=2254&amp;md5=84788c8541ef1b89b87b1ab7bff19abf" type="text/html" />
	</item>
		<item>
		<title>Grails und Eclipse</title>
		<link>http://www.k-oo.de/blog/2011/03/14/grails-und-eclipse/</link>
		<comments>http://www.k-oo.de/blog/2011/03/14/grails-und-eclipse/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 04:56:12 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[Entwicklungsumgebung]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=2126</guid>
		<description><![CDATA[Ich habe in der letzten Zeit das Thema Grails in diesen Blog etwas vernachlässigt. So ist es nun nach dieser Durststrecke an der Zeit, wieder einen Blog Eintrag zu diesem Thema zu schreiben (weitere könnten folgen). Einer meiner ersten Artikel zu Grails zeigte, wie man Grails und Eclipse zueinander bringt. Dieser Eintrag war so erfolgreich, [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe in der letzten Zeit das Thema Grails in diesen Blog etwas vernachlässigt. So ist es nun nach dieser Durststrecke an der Zeit, wieder einen Blog Eintrag zu diesem Thema zu schreiben (weitere könnten folgen).<br />
Einer meiner <a href="http://www.k-oo.de/blog/2007/02/03/komfort-grails-und-eclipse/">ersten Artikel zu Grails</a> zeigte, wie man <strong>Grails und Eclipse</strong> zueinander bringt. Dieser Eintrag war so erfolgreich, dass ich ihn auch als <a href="http://www.k-oo.de/blog/grails/komfort-grails-und-eclipse/">feste Seite</a> im Rahmen eines kleinen Tutorials in den Blog integriert habe.</p>
<div style="float:left;margin-right: 10px">
<img src="http://www.k-oo.de/blog/wp-content/uploads/2011/03/sts_grails_plugins.png" alt="" title="sts - eclipse grails plugins" width="242" height="500" class="alignnone size-full wp-image-2213" />
</div>
<p>Dies ist ein paar Monate her und die Unterstützung der Erstellung von Grails Anwendungen durch Eclipse ist stetig besser geworden.<br />
War es zum Anfang so, dass die mit Abstand beste IDE für Grails IDEA war, so holt das freie Eclipse immer mehr auf. Spätestens mit dem Wechsel der Grails Entwickler zu Springsource und der damit verbundenen Einbettung in die Eclipse basierte <a href="http://www.springsource.com/developer/sts">Springsource Tool Suite (STS)</a> hat sich eine Menge getan.</p>
<p>Mal abgesehen von dem Hauptspeicher &#8211; Hunger von STS fühle ich mich als alter Eclipse Nutzer gut aufgehoben. Mit Netbeans und IDEA konnte ich mich nie so richtig anfreunden.</p>
<p><img src="http://www.k-oo.de/blog/wp-content/uploads/2011/03/sts_grails_nav.png" alt="" title="sts grails navigation" width="109" height="91" class="alignnone size-full wp-image-2216" /> </p>
<p>Um den Grails Support zu aktivieren müssen die <strong>Grails und Groovy Extensions</strong> über den Reiter Extensions des STS Dashboards installiert werden (s. Screenshot). Danach gibt es für Grails Projekte eine eigene Perspektive mit Syntax Highlighting, Code Vervollständigung und einer übersichtlichen Navigation im Project Explorer.<br />
In der Toolbar gibt es in der Grails Perspektive einen Button <img src="http://www.k-oo.de/blog/wp-content/uploads/2011/03/sts_grails_button.png" alt="" title="sts grails button" width="21" height="22" class="alignnone size-full wp-image-2219" style="display:inline" /> zur Ausführung von Grails Befehlen (wie z.B. <code>run-app</code>).</p>
<p style="clear:both" />
Bei der Installation der Grails Extensions wird im Installationsverzeichnis des STS die aktuelle <strong>Grails Version</strong> abgelegt.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~ <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> springsource<span style="color: #000000; font-weight: bold;">/</span>
   grails-1.3.5
   grails-1.3.6				
   grails-1.3.7
   maven-2.2.1.RELEASE				
   roo-1.1.0.RELEASE			
   tc-server-developer-2.0.4.RELEASE
   sts-2.5.0.RELEASE</pre></div></div>

<p>Gibt es bei den <strong>Updates</strong> (Help -> check for Updates) eine neue Grails Version wird diese dort hinzugefügt. In den <strong>Preferences (Groovy -> Grails)</strong> muss man dann die neue Version für den Workspace übernehmen. Im Grails Projekt ist dann noch der <code>upgrade</code> <strong>Befehl</strong> notwendig.</p>
<p><strong>Fazit:</strong><br />
Die Grails Integration in Eclipse hat einen großen Schritt nach vorn getan. Vom Funktionsumfang dürfte IDEA immer noch führen. Grails Projekte werden dort allerdings nur in der kostenpflichtigen ULTIMATE Variante unterstützt.<br />
Die kostenfreien Entwicklungsumgebungen Netbeans und die Eclipse basierte STS unterscheiden sich kaum in der Grails Unterstützung. Hier entscheidet die persönliche Vorliebe über die IDE.</p>
<p><strong>Links:</strong><br />
<a href="http://stackoverflow.com/questions/233664/best-ide-for-grails-groovy">Diskussion zu diesem Thema auf stackoverflow.com</a></p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=2126&amp;md5=957065af38ddd941effd8c43d66854a9" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2011/03/14/grails-und-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=2126&amp;md5=957065af38ddd941effd8c43d66854a9" type="text/html" />
	</item>
		<item>
		<title>grum 0.3 &#8211; up to date</title>
		<link>http://www.k-oo.de/blog/2010/03/22/grum-0-3-up-to-date/</link>
		<comments>http://www.k-oo.de/blog/2010/03/22/grum-0-3-up-to-date/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 03:46:00 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=1579</guid>
		<description><![CDATA[Ich habe ein paar Stunden dafür verwendet mein auf Google Code gehostetes Projekt grum auf den Stand der Dinge zu bringen (es wurde ja auch langsam Zeit). Grum ist eine kleine Grails Anwendung zur Benutzerverwaltung, die es mir ermöglicht mit dem Web Framework Grails &#8220;zu spielen&#8221;. Ich habe bei der Umsetzung bewusst auf die vielen [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe ein paar Stunden dafür verwendet mein auf Google Code gehostetes Projekt <a href="http://code.google.com/p/grum">grum</a> auf den Stand der Dinge zu bringen (es wurde ja auch langsam Zeit). <strong>Grum</strong> ist eine kleine Grails Anwendung zur Benutzerverwaltung, die es mir ermöglicht mit dem Web Framework <a href="http://grails.org">Grails</a> &#8220;zu spielen&#8221;.</p>
<p>Ich habe bei der Umsetzung bewusst auf die vielen Grails Plugins verzichtet, um so wenig Seiteneffekte wie möglich zu haben und es auch für diejenigen einfach zu halten, die einen Einstieg in Grails suchen. So sind in Grum Lösungen enthalten, wie man z.B.:</p>
<ul>
<li>den Zugriff auf eine Mysql Datenbank realisiert</li>
<li>1:1, 1:n und n:m <a href="http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20(GORM).html">GORM</a> Beziehungen modelliert</li>
<li>eigene Tag Libs schreibt</li>
<li>die JSP Tag Lib <a href="http://displaytag.org">displaytag</a> verwendet, um die Daten seitenweise anzuzeigen, zu gruppieren, zu sortieren und in alle möglichen Formate (excel, csv, xml, pdf) zu exportieren</li>
<li>den Upload von Dateien ermöglicht</li>
<li>funktionale Tests mit dem <a href="http://www.grails.org/plugin/webtest">webtest Plugin</a> verwendet</li>
<li>und die Auslieferung von XML aufgrund von besonderen URL&#8217;s (kurz Content Negotiation) umsetzt</li>
</ul>
<p>Die neue Version 0.3 verwendet jetzt grails 1.2.1 und das Plugin webtest in der Version 2.0.3. Die <a href="http://grum.googlecode.com/files/grum-src-0.3.tar.gz">Sourcen</a>, die <a href="http://grum.googlecode.com/files/grum-sql-0.3.zip">SQL Dateien</a> zur Erstellung der Mysql Datenbank und ein <a href="http://grum.googlecode.com/files/grum-0.3.war">Webarchiv</a> mit allen notwendigen Bibliotheken stehen auf Google Code zum <a href="http://code.google.com/p/grum/downloads/list">Download</a> bereit.</p>
<p><strong>Nutztungshinweise:</strong><br />
Der Code kann frei verwendet werden, kann aber Fehler enthalten, für die ich keine Haftung übernehme. Die Lizenzbedingungen der verwendeten Bibliotheken sind einzuhalten.</p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1579&amp;md5=7bf859582df4d69918da90384e98a96b" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2010/03/22/grum-0-3-up-to-date/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1579&amp;md5=7bf859582df4d69918da90384e98a96b" type="text/html" />
	</item>
		<item>
		<title>Grails und displaytag &#8211; Paging leicht gemacht</title>
		<link>http://www.k-oo.de/blog/2010/03/05/grails-und-displaytag-paging-leicht-gemacht/</link>
		<comments>http://www.k-oo.de/blog/2010/03/05/grails-und-displaytag-paging-leicht-gemacht/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 15:40:07 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=1410</guid>
		<description><![CDATA[Wer sich nicht erst seit Grails mit Webanwendungen auf Java Basis beschäftigt, dem dürfte die JSP Taglib displaytag ein Begriff sein. Displaytag ermöglicht es ohne große Klimmzüge Tabellen in Java Server Pages auf mehrere Seiten aufzuteilen (Paging), zu sortieren, zu gruppieren und nach Excel, Csv, Xml und Pdf zu exportieren. Grails unterstützt &#8220;out of the [...]]]></description>
			<content:encoded><![CDATA[<p>Wer sich nicht erst seit Grails mit Webanwendungen auf Java Basis beschäftigt, dem dürfte die JSP Taglib <a href="http://displaytag.sourceforge.net/"><strong>displaytag</strong></a> ein Begriff sein. </p>
<p>Displaytag ermöglicht es ohne große Klimmzüge Tabellen in Java Server Pages auf mehrere Seiten aufzuteilen (<strong>Paging</strong>), zu <strong>sortieren</strong>, zu <strong>gruppieren</strong> und nach <strong>Excel, Csv, Xml und Pdf zu exportieren</strong>.<br />
Grails unterstützt &#8220;out of the box&#8221; nur das Paging und lange Zeit konnte man keine JSP Tag Libs in Grails verwenden, so dass man die restlichen Funktionalitäten entweder durch Plugins abbilden konnte oder selbst Hand anlegen musste.</p>
<p>Seit Grails 1.1 ist diese Beschränkung nun aufgehoben und der Test die beiden zu vereinen ist schon seit längerem erfolgreich abgeschlossen. Nur der Blog Eintrag darüber steht seit dem noch auf meiner ToDo Liste. Aber was lange währt wird gut (hoffe ich <img src='http://www.k-oo.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ).</p>
<p>Folgende Schritte sind zur Integration von displaytag in Grails notwendig:</p>
<h3>libs</h3>
<p>Zuerst sollten die Displaytag Bibliotheken neben dem Datenbank Treiber ins lib Verzeichnis kopiert werden.<br />
<img src="http://www.k-oo.de/blog/wp-content/uploads/2010/03/libs.jpg" alt="" title="displaytag Bibliotheken" width="360" height="139" class="aligncenter size-full wp-image-1536" /></p>
<h3>Displaytag Konfigurationsdatei</h3>
<p>Die Konfigurationsdatei von displaytag <a href="http://code.google.com/p/grum/source/browse/trunk/src/java/displaytag.properties">displaytag.properties</a> muss unter <code>src/java</code> erstellt werden. Der Aufbau dieser Datei ist in der <a href="http://displaytag.sourceforge.net/1.2/configuration.html">Doku</a> von displaytag beschrieben. Für mein <a href="http://code.google.com/p/grum">grum</a> Projekt sieht die Konfiguration so aus:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">export.<span style="color: #006633;">types</span><span style="color: #339933;">=</span>csv excel xml pdf
export.<span style="color: #006633;">excel</span><span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span>
export.<span style="color: #006633;">csv</span><span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span>
export.<span style="color: #006633;">xml</span><span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span>
export.<span style="color: #006633;">pdf</span><span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span>
export.<span style="color: #006633;">excel</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span>org.<span style="color: #006633;">displaytag</span>.<span style="color: #006633;">export</span>.<span style="color: #006633;">excel</span>.<span style="color: #006633;">DefaultHssfExportView</span>
export.<span style="color: #006633;">pdf</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span>org.<span style="color: #006633;">displaytag</span>.<span style="color: #006633;">export</span>.<span style="color: #006633;">DefaultPdfExportView</span>
export.<span style="color: #006633;">rtf</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span>org.<span style="color: #006633;">displaytag</span>.<span style="color: #006633;">export</span>.<span style="color: #006633;">DefaultRtfExportView</span>
export.<span style="color: #006633;">banner</span><span style="color: #339933;">=&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;exportlinks&quot;</span><span style="color: #339933;">&gt;</span>Export to<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
export.<span style="color: #006633;">amount</span><span style="color: #339933;">=</span>list
paging.<span style="color: #006633;">banner</span>.<span style="color: #006633;">placement</span><span style="color: #339933;">=</span>bottom
basic.<span style="color: #006633;">msg</span>.<span style="color: #006633;">empty_list</span><span style="color: #339933;">=</span>No data found.
<span style="color: #006633;">basic</span>.<span style="color: #006633;">msg</span>.<span style="color: #006633;">empty_list_row</span><span style="color: #339933;">=&lt;</span>tr <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;empty&quot;</span><span style="color: #339933;">&gt;&lt;</span>td colspan<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #339933;">&gt;</span>No data found.<span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;&lt;/</span>tr<span style="color: #339933;">&gt;&lt;/</span>tr<span style="color: #339933;">&gt;</span>
paging.<span style="color: #006633;">banner</span>.<span style="color: #006633;">full</span><span style="color: #339933;">=&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pagelinks&quot;</span><span style="color: #339933;">&gt;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{1}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>lt<span style="color: #339933;">;&amp;</span>lt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{2}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>lt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&amp;</span>nbsp<span style="color: #339933;">;</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">&amp;</span>nbsp<span style="color: #339933;">;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{3}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>gt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{4}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>gt<span style="color: #339933;">;&amp;</span>gt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>span<span style="color: #339933;">&gt;</span>
paging.<span style="color: #006633;">banner</span>.<span style="color: #006633;">first</span><span style="color: #339933;">=&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pagelinks&quot;</span><span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">&amp;</span>nbsp<span style="color: #339933;">;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{3}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>gt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{4}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>gt<span style="color: #339933;">;&amp;</span>gt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>span<span style="color: #339933;">&gt;</span>
paging.<span style="color: #006633;">banner</span>.<span style="color: #006633;">last</span><span style="color: #339933;">=&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pagelinks&quot;</span><span style="color: #339933;">&gt;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{1}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>lt<span style="color: #339933;">;&amp;</span>lt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&amp;</span>nbsp<span style="color: #339933;">;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{2}&quot;</span><span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&amp;</span>lt<span style="color: #339933;">;&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;&amp;</span>nbsp<span style="color: #339933;">;</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;</span>
paging.<span style="color: #006633;">banner</span>.<span style="color: #006633;">one_item_found</span><span style="color: #339933;">=&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pagebanner&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #cc66cc;">1</span> Record found. <span style="color: #006633;">Seite</span><span style="color: #339933;">:</span> <span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;</span>
paging.<span style="color: #006633;">banner</span>.<span style="color: #006633;">all_items_found</span><span style="color: #339933;">=&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pagebanner&quot;</span><span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#125;</span> Records found. <span style="color: #006633;">Seite</span><span style="color: #339933;">:</span> <span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;</span>
paging.<span style="color: #006633;">banner</span>.<span style="color: #006633;">some_items_found</span><span style="color: #339933;">=&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pagebanner&quot;</span><span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#125;</span> Records found, show <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">-</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#125;</span>. <span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;&lt;</span>br <span style="color: #339933;">/&gt;&lt;</span>br <span style="color: #339933;">/&gt;</span></pre></td></tr></table></div>

<h3>Displaytag Wrapper</h3>
<p>Dynamische Links und Formatierungen werden in displaytag über das Decorator Pattern umgesetzt. Der <a href="http://displaytag.sourceforge.net/1.2/tut_decorators.html">Decorator</a> wird in einer Wrapper Klasse implementiert, die in Grails natürlich in Groovy geschrieben ist. Meine Implementierung ist die Klasse <a href="http://code.google.com/p/grum/source/browse/trunk/src/groovy/de/koo/grum/groovy/util/DisplaytagWrapper.groovy">DisplaytagWrapper</a>, die im grum Projekt einen Link zu den Details der Benutzer erstellt und das Erstellungsdatum formatiert.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">de.koo.grum.groovy.util</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.displaytag.decorator.TableDecorator</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DisplaytagWrapper <span style="color: #000000; font-weight: bold;">extends</span> TableDecorator<span style="color: #009900;">&#123;</span>
   <span style="color: #003399;">String</span> getLinkToUser<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      def user <span style="color: #339933;">=</span> getCurrentRowObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;&lt;a href=<span style="color: #000099; font-weight: bold;">\&quot;</span>/grum/user/show/${user.id}<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;${user.username}&lt;/a&gt;&quot;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #003399;">String</span> getUserCreatedAt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      def user <span style="color: #339933;">=</span> getCurrentRowObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000000; font-weight: bold;">return</span> user.<span style="color: #006633;">createdAt</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;dd.MM.yyyy HH:mm&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Export Filter</h3>
<p>Beim Export in ein nicht HTML Format muss der content type für die Antwort an den Browser neu gesetzt werden. Damit dies nicht zu Problemen führt, sollte ein Filter in der web.xml Datei definiert werden, der möglichen Fehlern entgegenwirkt. Displaytag bringt mit der Klasse ResponseOverrideFilter bereits eine Implementierung dafür mit.</p>
<p>Um in Grails Änderungen an der <a href="http://code.google.com/p/grum/source/browse/trunk/src/templates/war/web.xml">web.xml</a> vornehmen zu können, müssen die Templates installiert werden:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">grails install-templates</pre></div></div>

<p>Danach befindet sich die <code>web.xml</code> im Verzeichnis <code>src/templates/war</code>. Für den Filter sind folgende Einträge notwendig.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ResponseOverrideFilter<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/filter-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.displaytag.filter.ResponseOverrideFilter<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/filter-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/filter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ResponseOverrideFilter<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/filter-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url-pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/filter-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h3>Einbindung in Groovy Server Page</h3>
<p>Hat man diese ganzen vorbereitenden Schritte absolviert, kann man sich endlich an die Verwendung von displaytag in einer Groovy Server Page machen.<br />
In meinem Beispiel <a href="http://code.google.com/p/grum/source/browse/trunk/grails-app/views/user/list.gsp">user/list.gsp</a> werden alle Benutzerdaten tabellarisch angezeigt. Die Tabelle ist durch das Attribut <code>sortable</code> nach Vor- und Nachnamen sortierbar (ohne erneuten Datenbankzugriff) und wird beim Erreichen der <code>pagesize</code> über das Attribut <code>partialList</code> auf mehrere Seiten verteilt.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;http://displaytag.sf.net&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;display&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>  
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
..
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:table</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;userList&quot;</span> <span style="color: #000066;">defaultsort</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">partialList</span>=<span style="color: #ff0000;">&quot;true&quot;</span> </span>
<span style="color: #009900;">      <span style="color: #000066;">decorator</span>=<span style="color: #ff0000;">&quot;de.koo.grum.groovy.util.DisplaytagWrapper&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">size</span>=<span style="color: #ff0000;">&quot;${resultSize}&quot;</span> <span style="color: #000066;">pagesize</span>=<span style="color: #ff0000;">&quot;${pageSize}&quot;</span> <span style="color: #000066;">requestURI</span>=<span style="color: #ff0000;">&quot;/grum/user/list&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;listing&quot;</span> <span style="color: #000066;">cellpadding</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">cellspacing</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">sort</span>=<span style="color: #ff0000;">&quot;list&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:column</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;linkToUser&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Userame&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>						
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:column</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;firstname&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Firstame&quot;</span> <span style="color: #000066;">sortable</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>						
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:column</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;lastname&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Lastname&quot;</span> <span style="color: #000066;">sortable</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>						
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:column</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;userCreatedAt&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Created At&quot;</span> <span style="color: #000066;">sortable</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>						
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/display:table<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...</pre></td></tr></table></div>

<p>Über zusätzliche Attribute (<code>export</code>, <code>group</code>) kann wie im Beispiel <a href="http://code.google.com/p/grum/source/browse/trunk/grails-app/views/contactData/list.gsp">contactData/list.gsp</a> auch der Export in die verschiedenen Ausgabeformate und eine Gruppierung der Einträge erreicht werden.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:table</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;contactDataList&quot;</span> <span style="color: #000066;">export</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">defaultsort</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">partialList</span>=<span style="color: #ff0000;">&quot;true&quot;</span> </span>
<span style="color: #009900;">      <span style="color: #000066;">decorator</span>=<span style="color: #ff0000;">&quot;de.koo.grum.groovy.util.DisplaytagWrapper&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">size</span>=<span style="color: #ff0000;">&quot;${resultSize}&quot;</span> <span style="color: #000066;">pagesize</span>=<span style="color: #ff0000;">&quot;${pageSize}&quot;</span> <span style="color: #000066;">requestURI</span>=<span style="color: #ff0000;">&quot;/grum/contactData/list&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;listing&quot;</span> <span style="color: #000066;">cellpadding</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">cellspacing</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">sort</span>=<span style="color: #ff0000;">&quot;list&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:setProperty</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;export.csv.filename&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;contactData.csv&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:setProperty</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;export.excel.filename&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;contactData.xls&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:setProperty</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;export.xml.filename&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;contactData.xml&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:setProperty</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;export.pdf.filename&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;contactData.pdf&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:setProperty</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;export.amount&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;list&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:column</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;linkContactDataToUser&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Name&quot;</span> <span style="color: #000066;">sortable</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">group</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>						
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:column</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;type&quot;</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;type&quot;</span> <span style="color: #000066;">sortable</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;display:column</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;data&quot;</span> <span style="color: #000066;">sortable</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/display:table<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p><strong>Fazit:</strong><br />
Einmal konfiguriert ist displaytag eine der tollsten Lösungen für java basierte Webanwendungen um Daten tabellarisch aufzulisten. Der Funktionsumfang übertrifft dabei weit die Standard Funktionalität von Grails. Die Kombination von Grails und displaytag kann ich daher nur jedem empfehlen.</p>
<p><strong>Links:</strong><br />
<a href="http://code.google.com/p/grum/source/browse/">grum Quellcode</a></p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1410&amp;md5=13ac2792a1d9e081dd1c46aa92715793" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2010/03/05/grails-und-displaytag-paging-leicht-gemacht/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1410&amp;md5=13ac2792a1d9e081dd1c46aa92715793" type="text/html" />
	</item>
		<item>
		<title>Grails 1.2 &#8211; der Gral für Webentwicklung in neuer Version</title>
		<link>http://www.k-oo.de/blog/2010/01/08/grails-1-2-der-gral-fur-webentwicklung-in-neuer-version/</link>
		<comments>http://www.k-oo.de/blog/2010/01/08/grails-1-2-der-gral-fur-webentwicklung-in-neuer-version/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 07:36:26 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=1454</guid>
		<description><![CDATA[Still und leise ist sie dahergekommen. Wie viele andere Groovy Projekte (Groovy 1.7, GPars 0.9, Gant 1.9) ist auch für Grails pünktlich zur Groovy&#038;Grails Exchange eine neue Version erschienen. Die finale Version 1.2 hat lange auf sich warten lassen. Eine stabile Version sollte es werden. Das war der Grund für die lange Beta und RC [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.k-oo.de/blog/wp-content/uploads/2010/01/Grails-The-search-is-over..jpg" rel="lightbox[1454]"><img src="http://www.k-oo.de/blog/wp-content/uploads/2010/01/Grails-The-search-is-over..jpg" alt="" title="Grails - The search is over." width="499" height="223" class="alignleft size-full wp-image-1457" /></a></p>
<p>Still und leise ist sie dahergekommen. Wie viele andere Groovy Projekte (Groovy 1.7, GPars 0.9, Gant 1.9) ist auch für Grails pünktlich zur Groovy&#038;Grails Exchange eine neue Version erschienen. Die finale Version 1.2 hat lange auf sich warten lassen.</p>
<p>Eine stabile Version sollte es werden. Das war der Grund für die lange Beta und RC Phase. So basiert Groovy 1.2 auch noch auf der Groovy Version 1.6.7.</p>
<p>Zur neuen Version hat Dierk König (Author von Groovy in Action) einen ausführlichen <a href="http://it-republik.de/jaxenter/artikel/Grails-1.2-ist-final-2800.html">Artikel</a> geschrieben, so dass an dieser Stelle nur eine kurze Liste neuer Funktionen folgt:</p>
<ul>
<li>Deklarative Abhängigkeiten für Bibliotheken innerhalb von Grails Anwendungen</li>
<li>Schnellere Sichten &#8211; Performancesteigerungen für Groovy Server Pages (GSP)</li>
<li>GORM defaults werden konfigurierbar</li>
<li>Named queries, die auch als Selektionsbasis für die dynamischen Finder Methoden dienen können</li>
<li>Ausbau, der eh schon sehr guten REST und JSON Unterstützung</li>
<li>die Grails documentation engine kann auch für andere (nicht auf Grails basierende) Anwendungen genutzt werden</li>
<li>Update auf Spring 3</li>
<li>fein granular konfigurierbare DataSources</li>
<li>erweiterte Unterstützung von annotierten Entities</li>
<li>Tomcat als Default Servlet Container. Andere Servlet Container wie z.B. Jetty werden ebenfalls unterstützt.</li>
</ul>
<p>Die komplette Liste der Änderungen könnt Ihr im <a href="http://jira.codehaus.org/browse/GRAILS?report=com.atlassian.jira.plugin.system.project:changelog-panel">Change Log</a> und den <a href="http://www.grails.org/1.2+Release+Notes">Release Notes</a> nachlesen.</p>
<p>Grails 1.2 steht auf der <a href="http://www.grails.org">Projektseite</a> zum <a href="http://www.grails.org/Download">Download</a> bereit. Für bestehende Grails Anwendungen reicht wie immer ein</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">grails upgrade</pre></div></div>

<p>Der Sprung von Version 1.1 auf 1.2 ist nicht so groß, wie der von Version 1.0 auf 1.1. Von daher sind bis jetzt nur <a href="http://adhockery.blogspot.com/2010/01/upgrading-grails-11-12.html">wenige Probleme</a> bekannt.</p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1454&amp;md5=d3587179eaf0aad1ad66814920d41a10" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2010/01/08/grails-1-2-der-gral-fur-webentwicklung-in-neuer-version/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1454&amp;md5=d3587179eaf0aad1ad66814920d41a10" type="text/html" />
	</item>
		<item>
		<title>Webtests für Grails Anwendungen</title>
		<link>http://www.k-oo.de/blog/2009/12/27/webtests-fur-grails-anwendungen/</link>
		<comments>http://www.k-oo.de/blog/2009/12/27/webtests-fur-grails-anwendungen/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 04:33:02 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=1413</guid>
		<description><![CDATA[Das auf Groovy basierende Webframework Grails ermöglicht in der Java Welt eine schnelle Entwicklung von Webapplikationen. Die Schnelligkeit erkauft man sich aber nicht durch den Verzicht auf Tests. Im Gegenteil. Mit dem Canoo &#8211; Webtest Plugin sind die Tests genauso schnell geschrieben, wie die Anwendung selbst (was aus meiner Sicht der einzige Weg ist dem [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.k-oo.de/blog/wp-content/uploads/2009/12/01_webtest_report.png" alt="canoo webtest Report" title="canoo webtest Report" width="499" height="189" class="alignleft size-full wp-image-1428" /></p>
<p>Das auf <a href="http://groovy.codehaus.org">Groovy</a> basierende Webframework <a href="http://www.grails.org">Grails</a> ermöglicht in der Java Welt eine schnelle Entwicklung von Webapplikationen. Die Schnelligkeit erkauft man sich aber nicht durch den Verzicht auf Tests. Im Gegenteil. </p>
<p>Mit dem <strong>Canoo &#8211; Webtest Plugin</strong> sind die Tests genauso schnell geschrieben, wie die Anwendung selbst (was aus meiner Sicht der einzige Weg ist dem Entwickler das Testen schmackhaft zu machen). </p>
<p>Für die <strong>Installation</strong> reicht ein simples:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&gt;</span> grails install-plugin webtest</pre></div></div>

<p>Und mit:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&gt;</span> grails create-webtest
WebTest name not specified. Please enter:
<span style="color: #000000; font-weight: bold;">&lt;</span>domain-name<span style="color: #000000; font-weight: bold;">&gt;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>copy<span style="color: #7a0874; font-weight: bold;">&#93;</span> Copying <span style="color: #000000;">1</span> <span style="color: #c20cb9; font-weight: bold;">file</span> to <span style="color: #000000; font-weight: bold;">&lt;</span>Pfad zur Grails App<span style="color: #000000; font-weight: bold;">&gt;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>copy<span style="color: #7a0874; font-weight: bold;">&#93;</span> Copying <span style="color: #000000;">1</span> <span style="color: #c20cb9; font-weight: bold;">file</span> to <span style="color: #000000; font-weight: bold;">&lt;</span>Pfad zur Grails App<span style="color: #000000; font-weight: bold;">&gt;/</span>webtest<span style="color: #000000; font-weight: bold;">/</span>tests
Web Test generated at webtest<span style="color: #000000; font-weight: bold;">/</span>tests<span style="color: #000000; font-weight: bold;">/&lt;</span>domain-name<span style="color: #000000; font-weight: bold;">&gt;</span>Test.groovy</pre></td></tr></table></div>

<p>erstellt man seinen <strong>ersten Test</strong> für eine Domainklasse von Grails. Alle Tests werden standardmäßig unter <code><Pfad zur Grails App>/webtest/tests</code> abgelegt. Ein <strong>generierter Test</strong> könnte so aussehen:<br />
<span id="more-1413"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">class GroupTest extends grails.util.WebTest <span style="color: #7a0874; font-weight: bold;">&#123;</span>
&nbsp;
    def testGroupListNewDelete<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	invoke      <span style="color: #ff0000;">'group'</span>
	verifyText  <span style="color: #ff0000;">'Home'</span>
&nbsp;
	verifyListSize <span style="color: #000000;">0</span>
&nbsp;
	clickLink   <span style="color: #ff0000;">'New Group'</span>
	verifyText  <span style="color: #ff0000;">'Create Group'</span>
	clickButton <span style="color: #ff0000;">'Create'</span>
	verifyText  <span style="color: #ff0000;">'Show Group'</span>, description:<span style="color: #ff0000;">'Detail page'</span>
	clickLink   <span style="color: #ff0000;">'List'</span>, description:<span style="color: #ff0000;">'Back to list view'</span>
&nbsp;
	verifyListSize <span style="color: #000000;">1</span>
&nbsp;
	group<span style="color: #7a0874; font-weight: bold;">&#40;</span>description:<span style="color: #ff0000;">'edit the one element'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	    showFirstElementDetails<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
	    clickButton <span style="color: #ff0000;">'Edit'</span>
	    verifyText  <span style="color: #ff0000;">'Edit Group'</span>
	    clickButton <span style="color: #ff0000;">'Update'</span>
	    verifyText  <span style="color: #ff0000;">'Show Group'</span>
	    clickLink   <span style="color: #ff0000;">'List'</span>, description:<span style="color: #ff0000;">'Back to list view'</span>
	<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
	verifyListSize <span style="color: #000000;">1</span>
&nbsp;
	group<span style="color: #7a0874; font-weight: bold;">&#40;</span>description:<span style="color: #ff0000;">'delete the only element'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	    showFirstElementDetails<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
	    clickButton <span style="color: #ff0000;">'Delete'</span>
	    verifyXPath xpath:  <span style="color: #ff0000;">&quot;//div[@class='message']&quot;</span>,
			text:   <span style="color: #000000; font-weight: bold;">/</span>.<span style="color: #000000; font-weight: bold;">*</span>Group.<span style="color: #000000; font-weight: bold;">*</span>deleted.<span style="color: #000000; font-weight: bold;">*/</span>,
			regex:  <span style="color: #c20cb9; font-weight: bold;">true</span>
	<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
	verifyListSize <span style="color: #000000;">0</span>
    <span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
    String ROW_COUNT_XPATH = <span style="color: #ff0000;">&quot;count(//div[@class='list']//tbody/tr)&quot;</span>
&nbsp;
    def verifyListSize<span style="color: #7a0874; font-weight: bold;">&#40;</span>int <span style="color: #c20cb9; font-weight: bold;">size</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
        ant.group<span style="color: #7a0874; font-weight: bold;">&#40;</span>description:<span style="color: #ff0000;">&quot;verify Group list view with <span style="color: #007800;">$size</span> row(s)&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
            verifyText  <span style="color: #ff0000;">'Group List'</span>
            verifyXPath xpath:      ROW_COUNT_XPATH,
                        text:       <span style="color: #c20cb9; font-weight: bold;">size</span>,
                        description:<span style="color: #ff0000;">&quot;<span style="color: #007800;">$size</span> row(s) of data expected&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">&#125;</span>
    <span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
    def showFirstElementDetails<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
        clickLink   <span style="color: #ff0000;">'1'</span>, description:<span style="color: #ff0000;">'go to detail view'</span>
    <span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></td></tr></table></div>

<p>und sollte natürlich auf die eigene Anwendung vor dem ersten Testlauf angepasst werden. <strong>Tests startet</strong> man entweder für eine TestSuite, einen TestCase oder einer Methode aus einem TestCase.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># TestSuite</span>
<span style="color: #000000; font-weight: bold;">&gt;</span> grails run-webtest
&nbsp;
<span style="color: #666666; font-style: italic;"># TestCase</span>
<span style="color: #000000; font-weight: bold;">&gt;</span> grails run-webtest <span style="color: #000000; font-weight: bold;">&lt;</span>webtest<span style="color: #000000; font-weight: bold;">&gt;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Methode aus einem TestCase</span>
<span style="color: #000000; font-weight: bold;">&gt;</span> grails run-webtest <span style="color: #000000; font-weight: bold;">&lt;</span>webtest<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #7a0874; font-weight: bold;">test</span> pattern<span style="color: #000000; font-weight: bold;">&gt;</span></pre></div></div>

<p>Für den Test wird versucht den ServletContainer zu starten. Bei laufender Grails Applikation empfiehlt es sich daher mit der Option <code>-nostart</code> zu arbeiten. Das Ergebnis wird detailliert in einer HTML Seite dargestellt, die nach dem Test sofort im Browser aufgerufen wird.</p>
<div style="float:left; margin-right:10px">
<img src="http://www.k-oo.de/blog/wp-content/uploads/2009/12/02_webtest_recorder.png" alt="webtest Recorder" title="webtest Recorder" width="200" height="294" class="alignleft size-full wp-image-1433" />
</div>
<p>Gerade das <strong>Testen von Formularen</strong> ist ziemlich stupide. Canoo Webtest bringt für diese Aufgabe einen <strong>Webrecorder</strong> mit. Dabei handelt es sich um ein <a href="https://www.canoo.com/webtestrecorder-dist/webtestrecorder.xpi"><strong>Firefox Plugin</strong></a>, mit dem die Bedienung der Webanwendung aufgezeichnet werden kann. Die einzelnen Testbefehle werden im <strong>Groovy, XML und Webdriver Format</strong>abgespeichert. Zusätzlich können <strong>XPath Abfragen</strong> getestet werden.</p>
<p style="clear:both" />
<p><strong>Fazit:</strong><br />
Testen muss nicht langweilig und stupide sein. Das Canoo Webtest Plugin für Grails ermöglicht das schnelle Erstellen von Tests, was zu einer <strong>höheren Testabdeckung</strong> der eigenen Webanwendung führt.<br />
Canoo Webtest lässt sich aber auch für Webanwendungen nutzen, die nicht auf Grails basieren. So könnte man es auch PHP oder Ruby Webanwendungen damit testen. Da Canoo Webtest auf dem Build Tool Ant basiert, ist es sehr einfach es in den Build Prozess einzubinden. Die Ergbenisse können dann auch im Continuous Integration Server Hudson angezeigt werden. Dies stellt sicher, dass die Tests dann auch zyklisch ausgeführt werden.</p>
<p>Somit kann eigentlich nichts mehr schief gehen. <img src='http://www.k-oo.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Links:</strong><br />
<a href="http://www.grails.org/Functional+Testing">Canoo Webtest Plugin</a><br />
<a href="https://www.canoo.com/webtestrecorder-dist/webtestrecorder.xpi">Firefox Plugin &#8211; Webtest Recorder</a><br />
<a href="http://it-republik.de/jaxenter/artikel/Testautomatisierung-mit-WebTest-2761.html?print=1">Testautomatisierung mit WebTest</a><br />
<a href="http://wiki.hudson-ci.org/display/HUDSON/WebTest+Presenter+Plugin">Hudson Plugin</a></p>
<p><strong>Update:</strong><br />
Mit Grails 1.2 wird Webtest nicht mehr im Bundle mit ausgeliefert. Von daher steht erst einmal ein Download des Plugins an, dass dann auch gleich in der Version 2 daherkommt und zahlreiche Änderungen mit sich bringt.<br />
Unter anderem wechselt der Ort für das webtest Verzeichnis. Es liegt jetzt unterhalb des Test Verzeichnisses. Alte Tests bedürfen auch einer Änderung bevor sie wieder laufen. Die Testmethoden müssen jetzt mit <code>void</code> und nicht mehr mit <code>def</code> angelegt werden.</p>
<p>Gestartet werden die Tests jetzt mit:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&gt;</span> grails test-app <span style="color: #660033;">-functional</span></pre></div></div>

<p>Weitere Änderungen kann man unter diesem <a href="http://refactor.com.au/blog/grails-webtest-plugin-120-released">Link</a> oder auf der <a href="http://grails.org/plugin/webtest">Seite des Plugins</a> nachlesen.</p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1413&amp;md5=23df059f01a74d991e906590229b0465" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2009/12/27/webtests-fur-grails-anwendungen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1413&amp;md5=23df059f01a74d991e906590229b0465" type="text/html" />
	</item>
		<item>
		<title>Grails Podcast wird 100</title>
		<link>http://www.k-oo.de/blog/2009/11/29/grails-podcast-wird-100/</link>
		<comments>http://www.k-oo.de/blog/2009/11/29/grails-podcast-wird-100/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 14:32:41 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[podcast]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=1375</guid>
		<description><![CDATA[Eine der wichtigsten Resourcen, wenn man sich mit Groovy und Grails beschäftigt, ist aus meiner Sicht der Grails Podcast von und mit Sven Haiges und Glen Smith. Der Podcast, der alle 2 Wochen in englischer Sprache erscheint, hat nun die Folge 100 erreicht. Alles Gute von meiner Seite zu diesem Ereignis und vielen Dank für [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.k-oo.de/blog/wp-content/uploads/2009/11/head_grailspodcast.png" alt="grailspodcast logo" title="grailspodcast logo" width="499" height="105" class="alignleft size-full wp-image-1376" /></p>
<p>Eine der wichtigsten Resourcen, wenn man sich mit Groovy und Grails beschäftigt, ist aus meiner Sicht der <a href="http://www.grailspodcast.com"><strong>Grails Podcast</strong></a> von und mit Sven Haiges und Glen Smith.</p>
<p>Der Podcast, der alle 2 Wochen in englischer Sprache erscheint, hat nun die <strong>Folge 100</strong> erreicht.<br />
Alles Gute von meiner Seite zu diesem Ereignis und vielen Dank für die zahlreichen Informationen und News der letzten Jahre rund um die Themen Groovy und Grails.</p>
<p>Macht weiter so.</p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1375&amp;md5=fac5ad565b2715b859557d101ed43b97" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2009/11/29/grails-podcast-wird-100/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1375&amp;md5=fac5ad565b2715b859557d101ed43b97" type="text/html" />
	</item>
		<item>
		<title>Warum Groovy</title>
		<link>http://www.k-oo.de/blog/2009/11/23/warum-groovy/</link>
		<comments>http://www.k-oo.de/blog/2009/11/23/warum-groovy/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 10:22:21 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[web2.0]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=1324</guid>
		<description><![CDATA[Aus meiner Sicht ist Groovy, die dynamische Sprache für die Java Virtual Machine, auf der großen Hype Kurve am Punkt der technischen Realität angekommen. Mit Scala und Clojure werden statt dessen gerade 2 neue Programmiersprachen durch die Gemeinde der Java Jünger getrieben. So ist es an der Zeit einmal zu hinterfragen, was man selbst bis [...]]]></description>
			<content:encoded><![CDATA[<div style="float:left; margin-right: 5px"><img src='http://www.k-oo.de/blog/wp-content/uploads/2007/01/groovy.png' alt='Groovy Logo' /></div>
<p>Aus meiner Sicht ist <a href="http://groovy.codehaus.org"><strong>Groovy</strong></a>, die dynamische Sprache für die Java Virtual Machine, auf der großen Hype Kurve am Punkt der technischen Realität angekommen. Mit <a href="http://www.scala-lang.org/">Scala</a> und <a href="http://clojure.org/">Clojure</a> werden statt dessen gerade 2 neue Programmiersprachen durch die Gemeinde der Java Jünger getrieben.</p>
<p style="clear:both;" />
So ist es an der Zeit einmal zu hinterfragen, was man selbst bis jetzt mit Groovy implementiert hat, ob man dabei bleibt oder doch auf den Scala Zug aufspringt.</p>
<p>Dierk König, der Autor von &#8220;Groovy in Action&#8221; (dem besten Fachbuch, das ich in letzter Zeit gelesen habe), hat einmal folgende 7 Anwendungsmuster für Groovy herausgearbeitet:</p>
<blockquote><p>
Super Glue, Liquid Heart, Keyhole Surgery, Smart Configuration, Unlimited Openness, House-Elf Scripts, Prototype
</p></blockquote>
<p>Oder nicht ganz so prosaisch, als:</p>
<ul>
<li>Bindeglied zwischen Java Komponenten (wie z.B. Spring und Hibernate in Grails)</li>
<li>Auslagerung der Buisiness Logik, um sie dynamisch auf Veränderungen anpassen zu können</li>
<li>Eingriffsmöglichkeit in laufende Applikationen</li>
<li>Erweiterung der Konfiguration mit den Mitteln einer Programmiersprache (um endlich das plumpe XML loszuwerden)</li>
<li>die leichte Veränderung von Code zur Laufzeit</li>
<li>Hilfe für alle Aufgaben, die durch die Programmierung anfallen (Build automation, continuous integration, deployment, installer, service monitoring, reports, statistics, automated documentation, functional tests, HTML scraping, Web remote control, XML-RPC, WebServices)</li>
<li>Tool zur schnellen Erstellung von Prototypen, mit der Möglichkeit diese später auf Java portieren zu können.</li>
</ul>
<p>Doch zurück zum Ausgangspunkt. Was mache ich mit Groovy? </p>
<p>Zuerst einmal schreibe ich 95 % aller neuen Tests in Groovy. Die knackige Syntax, die perfekte Interoperabilität mit Java und die gute (aber verbesserungsfähige) Integration in Eclipse machen die Erstellung von Tests sehr viel weniger lästig. Zudem gibt es kleinere Web- und Webservices Applikationen auf Basis von <a href="http://grails.org/">Grails</a> (dem Webframwork, das seinerseits ebenfalls auf Groovy basiert), sowie Tools, die rein in Groovy geschrieben sind.</p>
<p>Letztendlich kann man sagen, der Hype ist dem Alltag gewichen und Groovy passt sich perfekt in die tägliche Arbeit ein. Mit <a href="http://griffon.codehaus.org/">Griffon</a> und <a href="http://gpars.codehaus.org/">GPars</a> stehen 2 weitere Frameworks für Swing Applikationen und Nebenläufige Programmierung (Threads) auf Groovy Basis zur Verfügung. Und eine lebendige Community hat sich um diese dynamische Sprache gebildet. Ein Umstieg auf Scala oder Closure kommt somit für mich momentan nicht in Betracht.</p>
<p>Und mal ganz ehlich, wenn die Kinder fragen: &#8220;Papa was machst Du?&#8221;, klingt &#8220;ich programmiere Groovy&#8221; viel cooler als &#8220;Ich programmiere Scala&#8221;. <img src='http://www.k-oo.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Links:</strong><br />
<a href="http://www.slideshare.net/gr8conf/groovy-usage-patterns-by-dierk-knig">Groovy Usage Patterns by Dierk König</a></p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1324&amp;md5=ca71a467a8ade16ce8986fc55483a3d8" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2009/11/23/warum-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=1324&amp;md5=ca71a467a8ade16ce8986fc55483a3d8" type="text/html" />
	</item>
		<item>
		<title>kein kostenloser Developer Account mehr bei Morph App Space</title>
		<link>http://www.k-oo.de/blog/2009/08/06/kein-kostenloser-developer-account-mehr-bei-morph-app-space/</link>
		<comments>http://www.k-oo.de/blog/2009/08/06/kein-kostenloser-developer-account-mehr-bei-morph-app-space/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 15:59:48 +0000</pubDate>
		<dc:creator>gklinkmann</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.k-oo.de/blog/?p=995</guid>
		<description><![CDATA[Das erste, was man nach dem Urlaub (ohne Internet) macht, ist seine Mails zu lesen. Darunter war eine von Morph AppSpace, von denen ich in einem früheren Beitrag noch über die kostenlosen Developer Accounts für Grails Applikationen berichtet habe. Doch was musste ich da jetzt lesen: As part of our efforts to focus on providing [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.k-oo.de/blog/wp-content/uploads/2009/01/grails_hosting_morph.jpg" alt="morph AppSpace logo" title="morph AppSpace logo" width="150" height="79" class="alignleft size-full wp-image-589" /></p>
<p>Das erste, was man nach dem Urlaub (ohne Internet) macht, ist seine Mails zu lesen. Darunter war eine von Morph AppSpace, von denen ich in einem <a href="http://www.k-oo.de/blog/2009/01/21/hosting-von-grails-anwendungen/">früheren Beitrag</a> noch über die <strong>kostenlosen Developer Accounts</strong>  für  Grails Applikationen berichtet habe. Doch was musste ich da jetzt lesen:</p>
<blockquote><p>As part of our efforts to focus on providing quality next-generation products and following our previous announcement, effective Monday, July 13, 2009, we are discontinuing FREE AppSpaces for customers without paid AppSpaces.</p></blockquote>
<p>Also erst zahlen dann kann man weiter kostenlos Entwicklungsstände deployen. </p>
<p>So wird auch meine kleine Applikation <a href="http://code.google.com/p/grum"><strong>Grum</strong></a> nicht mehr bei Morph AppSpace gehostet. Ich werde mir mal die <strong>Google App Engine</strong> anschauen. Dafür dürften aber ein paar kleine Änderungen notwendig sein (z.B. JPA statt Hibernate für die Persistenz).<br />
Wenn es soweit ist, werde ich meine Erfahrungen natürlich hier im Blog schildern.</p>
<p><strong>Ich will wieder zurück in den Urlaub.</strong></p>
 <p><a href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=995&amp;md5=287dd20510650c0bae4546963cf9f07d" title="Flattr" target="_blank"><img src="http://www.k-oo.de/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.k-oo.de/blog/2009/08/06/kein-kostenloser-developer-account-mehr-bei-morph-app-space/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.k-oo.de/blog/?flattrss_redirect&amp;id=995&amp;md5=287dd20510650c0bae4546963cf9f07d" type="text/html" />
	</item>
	</channel>
</rss>

