goldstift's blogspot my 2 cent

Posts mit dem Label tutorial werden angezeigt. Alle Posts anzeigen
Posts mit dem Label tutorial werden angezeigt. Alle Posts anzeigen

25 September 2011

SpringRoo: Entity-Klassen und JPA-Repositories mit SpringRoo erstellen

Dies ist der zweite Artikel in meiner Tutorial-Reihe zu SpringRoo 1.2.0 in der die Beispiel-Anwendung "photooapp" entwickelt wird.

Vorbedingungen

In diesem Beitrag geht es um die initiale Erstellung der Roo-Anwendung. Hierfür müssen folgende Vorbedingungen erfüllt sein:

Lokalen Datenbankserver installieren (falls notwendig)

Wir gehen davon aus, dass die Anwendung später mit einer MySQL 5.1-Datenbank betrieben werden soll, die auf dem gleichen Server läuft wie die Anwendung.
Um eine ähnliche Umgebung für die Entwicklung zu verwenden, benötigen wir eine lokale MySQL-Installation. Für diejenigen ohne eine lokale Installation ist die wohl einfachste und schnellste Art dies zu erreichen wahrscheinlich das XAMPP-Paket von Apachefriends. Es kann über die URL http://www.apachefriends.org/de/xampp.html heruntergeladen werden.

Ist die Software installiert und der MySQL-Datenbankserver gestartet, können mit den folgenden beiden Befehlen die Datenbank und der zugehörige Benutzer erstellt werden. Diese Befehle sind auch im MySQL-Setup-Skript enthalten:

$ /Applications/XAMPP/xamppfiles/bin/mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.1.44 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE DATABASE photooapp DEFAULT CHARSET=utf8;
mysql> GRANT ALL ON photooapp.* TO photooapp@localhost IDENTIFIED BY 'pho!00App';
mysql> exit
Bye
$

Nun sollten alle notwendigen Vorbedingungen erfüllt sein und wir können in der SpringRoo shell weitermachen.

Datenmodell-Klassen in SpringRoo erstellen

Für die Demo-Anwendung "Photooapp" wurde folgendes (vorläufiges) Datenmodell erstellt, das wir nun in SpringRoo umsetzen wollen:

Hierzu öffnen wir die SpringRoo Shell:
ahe:(git)photooapp[master]/$ ~/dev/tools/spring-roo-1.2.0.M1/bin/roo.sh
____ ____ ____
/ __ \/ __ \/ __ \
/ /_/ / / / / / / /
/ _, _/ /_/ / /_/ /
/_/ |_|\____/\____/ 1.2.0.M1 [rev 1fa252f]


Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
...
roo> script --file log.roo --lineNumbers true

Nun gibt es zwei Möglichkeiten:

a) Man tippt die folgenden Befehle auf der Roo-Shell ein:
project de.goldstift.photoo
jpa setup --provider HIBERNATE --database MYSQL --databaseName photooapp --userName photooapp --hostName 127.0.0.1 --password pho!00App

entity --class ~.domain.Tag --activeRecord false --testAutomatically
field string --fieldName name --notNull --sizeMin 2
field string --fieldName lowerCaseName --notNull --sizeMin 2

entity --class ~.domain.Person --activeRecord false --testAutomatically
field string --fieldName lastname --notNull --sizeMin 2
field string --fieldName firstname
field string --fieldName nickname --notNull

entity --class ~.domain.Event --activeRecord false --testAutomatically
field string --fieldName name --notNull --sizeMin 2
field date --fieldName fromDate --type java.util.Date --dateTimeFormatPattern "yyyy-MM-dd HH:mm:ss"
field date --fieldName toDate --type java.util.Date --dateTimeFormatPattern "yyyy-MM-dd HH:mm:ss"

entity --class ~.domain.Folder --activeRecord false --testAutomatically
field string --fieldName title
field date --fieldName createDate --type java.util.Date --dateTimeFormatPattern "yyyy-MM-dd HH:mm:ss"
field string --fieldName systemPath --notNull --sizeMin 1
field string --fieldName urlPath --notNull --sizeMin 1
field boolean --fieldName writable --primitive false

entity --class ~.domain.PhotoFile --activeRecord false --testAutomatically
field reference --fieldName folder --type ~.domain.Folder --cardinality MANY_TO_ONE --fetch EAGER
field string --fieldName filename --notNull
field number --fieldName width --notNull --type java.lang.Short
field number --fieldName height --notNull --type java.lang.Short

entity --class ~.domain.Photo --activeRecord false --testAutomatically
field string --fieldName title
field string --fieldName description
field string --fieldName thumbnail --notNull
field reference --fieldName thumbnailFile --type ~.domain.PhotoFile --cardinality MANY_TO_ONE --fetch EAGER
field reference --fieldName previewFile --type ~.domain.PhotoFile --cardinality MANY_TO_ONE --fetch EAGER
field reference --fieldName originalFile --type ~.domain.PhotoFile --cardinality MANY_TO_ONE --fetch EAGER
field date --fieldName importDate --type java.util.Date --dateTimeFormatPattern "MS"
field date --fieldName shotDate --type java.util.Date --dateTimeFormatPattern "MS"
field set --fieldName tags --type ~.domain.Tag --cardinality MANY_TO_MANY --fetch EAGER
field set --fieldName persons --type ~.domain.Person --cardinality MANY_TO_MANY --fetch EAGER
field set --fieldName events --type ~.domain.Event --cardinality MANY_TO_MANY --fetch EAGER

repository jpa --interface ~.repository.TagRepository --entity ~.domain.Tag
repository jpa --interface ~.repository.EventRepository --entity ~.domain.Event
repository jpa --interface ~.repository.PersonRepository --entity ~.domain.Person
repository jpa --interface ~.repository.PhotoRepository --entity ~.domain.Photo
service --interface ~.service.TagService --entity ~.domain.Tag
service --interface ~.service.EventService --entity ~.domain.Event
service --interface ~.service.PersonService --entity ~.domain.Person
service --interface ~.service.PhotoService --entity ~.domain.Photo

json all
web mvc setup
web mvc all --package ~.web

oder

b) man importiert die Befehle als Roo-Skript (speichern als "log.roo") mit Hilfe des folgenden Befehls:

roo> script --file log.roo --lineNumbers true

Anschließend kann die Anwendung über die folgenden Maven Befehle gebaut und gestartet werden:

ahe:(git)photooapp[master]/$ mvn clean package
(...)
ahe:(git)photooapp[master]/$ mvn jetty:run

Durch letzteren Befehl wird die Anwendung in einem Jetty ApplicationServer gestartet, wodurch sie unter http://localhost:8080/photooapp verfügbar sein sollte.

Die komplette Anwendung ist bei github verfügbar unter https://github.com/aheusingfeld/photooapp


Weiterführende Links

Weitere Artikel der Reihe

23 September 2011

Starting PhotooApp - A SpringRoo tutorial application

Ich hatte bereits im Februar angekündigt, dass ich hier ein paar Artikel über SpringRoo schreiben würde, und nutze nun das Erscheinen des neuen Meilensteins um damit zu beginnen.

Die Idee

Vor ein paar Tagen ist endlich SpringRoo 1.2.0.M1 erschienen, welches der erste sog. Milestone der nächsten Version von SpringRoo ist. Das Besondere hieran ist die Unterstützung des Repository- oder auch DAO-Models, welches im Gegensatz zu dem sog. ActiveRecord-Model steht. Bisher verwendete SpringRoo zwingend das ActiveRecord-Model. Dank dieser Neuerung kann SpringRoo nun endlich in Kombination mit Spring Data JPA genutzt werden, was viele Vorteile und einige neue Möglichkeiten gerade im Bereich der Finder eröffnet.
Mein Ziel ist anhand einer Beispiel-Anwendung/ Demo-App die Möglichkeiten von SpringRoo zu demonstrieren und Workarounds für bekannte Unschönheiten aufzuzeigen.

Auf Grund persönlicher Präferenzen wird die Demo-App eine serverbasierte Fotoverwaltung, die sowohl von mobilen Endgeräten als auch von Desktop-PCs genutzt werden kann. Als Feature sollen die mobilen Endgeräte Fotos und Videos an die Anwendung übermitteln können, so dass diese direkt für andere Nutzer verfügbar sind.


Anforderungen

Hier die bisherigen Anforderungen:
  1. Die Anwendung muss Fotos aus einem Dateisystemordner importieren können
  2. Die Anwendung muss während des Imports Minibilder/ Thumbnails der Originale erstellen, die eine maximale Kantenlänge von 250px haben
  3. Die Anwendung muss während des Imports Vorschaubilder/ Previews der Originale erstellen, die eine maximale Kantenlänge von 1280px haben
  4. Ein Foto hat folgende Eigenschaften
    1. Titel
    2. Beschreibung
    3. Thumbnail-Datei (Fotodatei)
    4. Vorschau-Datei (Fotodatei)
    5. Original-Datei (Fotodatei)
    6. Importdatum
    7. Erstellungsdatum
  5. Eine Fotodatei hat folgende Eigenschaften
    1. Dateisystemordner
    2. dateiname
    3. Breite
    4. Höhe
  6. Die Anwendung soll die EXIF-Daten eines Fotos anzeigen können
  7. Ein Foto muss keinem oder beliebig vielen Stichwörtern zugeordnet werden können
  8. Ein Foto muss keiner oder beliebig vielen Personen zugeordnet werden können, die auf dem Photo zu sehen sind
  9. Ein Foto muss keinem oder beliebig vielen Events zugeordnet werden können
  10. Ein Event hat folgende Eigenschaften
    1. Name
    2. Von-Datum
    3. Bis-Datum
  11. Fotos müssen anhand von folgenden UND-verknüpften Filterkriterien gesucht werden können
    1. Stichwörter (Suchfeld mit Vorschlagswerten)
    2. Personen (Suchfeld mit Vorschlagswerten)
    3. Events (Suchfeld mit Vorschlagswerten)
    4. Name des Dateisystemordners
    5. Titel des Fotos
    6. Erstellungsdatum in gewähltem Zeitraum
  12. Suchergebnislisten müssen eine eindeutige, wiederverwendbare URL haben
  13. Die Anwendung sollte einen Präsentations-/ Slideshow-Modus für Suchergebnislisten unterstützen, welcher die Vorschaubilder der Listeneinträge für jeweils 3 Sekunden anzeigt 

Planung

Diese Anforderungen werde ich in folgende Schritte (und Blog-Posts) aufteilen:

Weitere Ideen und Vorschläge können gerne als Kommentar gestellt werden.

Die Demo-App ist bei Github unter der Adresse https://github.com/aheusingfeld/photooapp verfügbar.

UPDATE 24.09.2011 23:00h:
- Anforderungen in Deutsch übersetzt
- Liste der geplanten Blogposts/ weiteren Schritte erstellt

Vielen Dank für Euer Feedback und Euer Interesse.

13 Februar 2011

Broken special chars in Spring Roo?

This is the first post in an upcoming series of posts on Spring Roo (see footer for details an Roo).

Problem: Special chars and Umlauts are not correctly displayed in my Roo-Application

[german version]
There are often questions and support requests on the above named topic in Spring Roo-Forum. Mostly questioners write that german "Umlauts" like ä, ö, ü and ß or other special chars in cyrillic are not correctly display or saved to the database. With the following post I'd like to review the most common sources of the problem and come up with solutions.

Encoding of the HTML/ JSP page

Roo generated JSPs are always delivered with UTF-8 encoding. In case you write your additional JSPs by hand, you should assure these pages are also delivered to the browser in UTF-8 encoding so the form data will be correctly send on submit.
This can be achieved by specifying the following line of code at the beginning of each JSP:
<jsp:directive.page contenttype="text/html;charset=UTF-8"
   pageencoding="UTF-8"/>

To show you an example where to exactly put this, the "default.jspx", which serves a frame for all other JSP pages via Apache Tiles, contains the following lines to preserve UTF-8 encoding in the resulting HTML:
<html xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:tiles="http://tiles.apache.org/tags-tiles" xmlns:spring="http://www.springframework.org/tags" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" >  
 
 <jsp:output doctype-root-element="HTML" doctype-system="about:legacy-compat" />
 
 <jsp:directive.page contentType="text/html;charset=UTF-8" />  
  
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<!-- ... -->

To check whether your page is delivered in UTF-8 encoding, open it in your browser and have a look at menu "View > Character Encoding".

CharacterEncodingFilter in web.xml file

This is the most common point of failure. We're talking about the order in which the <filter-mapping>-Tags occur in your "src/main/webapp/WEB-INF/web.xml". These tags define in which order the filters are executed on each HTTP-Request.
Roo generates the correct order since Version 1.1.1! Previous versions are still buggy.

The correct order looks like the following:
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>HttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

In case you want to change the order it is important to understand at least a minimum of the inner workings of these filters:
To avoid problems with the encoding of your special chars, "CharacterEncodingFilter" has to be run before any other filter has worked on the request data!
For this reason the general advice is: the <filter-mapping> for CharacterEncodingFilter has to be at the first position in your "web.xml" (See ROO-1698 for an explanation - the charset CANNOT be set to the request after the InputStream has been read)!

Database connection

The last point is to assure that your application communicates with the database via unicode with a default encoding of UTF-8.

As Roo generates the correct connection string for MySQL since "the early days" there haven't been many bugs with this lately.
The connection string can be configured in "src/main/resources/META-INF/spring/database.properties" and looks like the following for MySQL:
database.url=jdbc:mysql://[YOUR_DB_SERVER]:3306/[YOUR_DB_NAME]?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8

Conclusion

Since version 1.1.1 Spring Roo provides a (by now) bug free support for special chars and umlauts, which as been tested with various languages worldwide.

If you have any questions on Spring Roo or the topic named above you can find competent assistance in the Roo-Forum.

References/ Links used in the text


Spring Roo is a Code-Generation-Tool for Software development in Java. It is a lightweight developer tool that makes it fast and easy to deliver instant results. Best of all, you code 100% in Java and get to reuse all your existing Java knowledge, skills and experience.

There are already many Add-Ons available to customize Roo to your special needs. In case you don't find an Add-On that fits your needs, you can easily create your own Add-On in just a few steps.

10 Februar 2011

Umlaute und Sonderzeichen in Spring Roo?

Dies ist der erste in einer Reihe von Blog-Posts über Spring Roo (Erläuterung siehe unten).
[english version]

Problem: Sonderzeichen und Umlaute werden in meiner Roo-Anwendung nicht korrekt angezeigt


Im Spring Roo-Forum gibt es öfter Anfragen, die o.g. Problem beschreiben, dass deutsche Umlaute wie ä, ö, ü und ß nicht korrekt gespeichert oder "kaputt" übertragen werden. Im Folgenden möchte ich kurz die häufigsten Fehlerquellen und Lösungen aufzeigen.

Zeichensatz der HTML-/ JSP-Seite

Durch Roo generierte JSPs werden immer im Zeichensatz UTF-8 ausgeliefert. Schreibt man eigene JSPs bspw. mit Formularen, sollte diese HTML bzw. JSP-Seite als Zeichensatz ebenfalls UTF-8 verwenden. Dies erreicht man in dem am Anfang der JSP die folgende Zeile eingefügt wird:
<jsp:directive.page contenttype="text/html;charset=UTF-8"
   pageencoding="UTF-8"/>

Am Anfang der "default.jspx", die über Apache Tiles als "Rahmen" für alle anderen JSP-Seiten gilt, sind z.B. folgende Angaben zum Encoding/ Zeichensatz enthalten:
<html xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:tiles="http://tiles.apache.org/tags-tiles" xmlns:spring="http://www.springframework.org/tags" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" >  
 
 <jsp:output doctype-root-element="HTML" doctype-system="about:legacy-compat" />
 
 <jsp:directive.page contentType="text/html;charset=UTF-8" />  
  
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<!-- ... -->

Ist sichergestellt, dass die Seiten im Zeichensatz "UTF-8" ausgeliefert werden (dies kann im Browser meist im Menüpunkt "Ansicht > Zeichensatz" kontrolliert werden), die Sonderzeichen werden aber trotzdem falsch übertragen, ist dies nicht die Fehlerursache.

CharacterEncodingFilter in der web.xml

Dieser Punkt ist der häufigste Fehler. Es geht hierbei um die Reihenfolge der <filter-mapping>-Tags in der Datei "web.xml". Diese Tags geben an, in welcher Reihenfolge die einzelnen Filter bei einem HTTP-Request durchlaufen werden.
Roo generiert leider erst seit Version 1.1.1 per Default die korrekte Reihenfolge, wie folgt aussieht:

<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>HttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Will man die Reihenfolge der Filter ändern, ist es wichtig, deren Bedeutung zu verstehen:
Damit Fehler in der Behandlung von Texten mit Sonderzeichen ausgeschlossen werden, sollte der "CharacterEncodingFilter" durchlaufen worden sein, bevor die Requestdaten in irgendeiner Form weiterverarbeitet werden.
Aus diesem Grund lautet die Empfehlung: das <filter-mapping> für den CharacterEncodingFilter muss in der "web.xml" an erster Stelle stehen (Erklärung siehe ROO-1698)!

Datenbankverbindung

Zu guter Letzt sollte sichergestellt werden, dass auch die Kommunikation mit der Datenbank über Unicode bzw. mit dem Standardzeichensatz UTF-8 geführt wird.

Kommt als Datenbank bspw. MySQL zum Einsatz, generiert Roo automatisch die Unicode-Unterstützung über folgende Konfiguration in der Datei "src/main/resources/META-INF/spring/database.properties":
database.url=jdbc:mysql://[YOUR_DB_SERVER]:3306/[YOUR_DB_NAME]?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8

Fazit

Seit Version 1.1.1 verfügt Spring Roo über eine (bisher) fehlerfreie Unterstützung für Sonderzeichen, die bereits in diversen Sprachen getestet wurde.
Bei Fragen und Problemen findet man im Roo-Forum auf jeden Fall kompetente Hilfe.

Im Text verwendete, weiterführende Links


Spring Roo ist ein Code-Generierungs-Werkzeug für die Softwareentwicklung, welches Entwickler in die Lage versetzt schnell und unkompliziert vorzeigbare Ergebnisse bspw. in Form von benutzbaren Prototypen zu liefern. Im Gegensatz zu anderen Werkzeugen, Frameworks und Tools entwickelt man mit Spring Roo zu 100% in Java.

Für die Anpassung oder Erweiterung von Roo bspw. durch eigene Add-Ons kann auf vorhandenes Java-Wissen und -Erfahrung aufgebaut werden. Unterstützt durch die geringen Einstiegshürden und die hohe Modularisierung, kann so jedes Projekt leicht an die ganz speziellen, individuellen Bedürfnisse angepasst und einmal geschriebene Komponenten oder Add-Ons wiederverwendet werden.

Update 12.02.2011 23:50h:
  • Frage eingearbeitet: "Setzt Roo diese Einstellungen automatisch oder muss man diese selbst anpassen?" - siehe Fazit
  • verschiedene Verbesserungsvorschläge eingearbeitet und Tippfehler korrigiert