Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

December 2, 2009

Spring Webanwendung generieren

Inspiriert durch den Artikel Spring ROO - Codegenerierung "the Spring Way" von Mike Wiesner in Novemberausgabe des Java Magazins, probierte ich das neue Framework vor Kurzem mal aus. Der Ansatz CRUD-Anwendungen zu generieren ist zwar nicht neu, allerdings wirkt die Entwicklungsumgebung enorm leistungsstark. Zudem erscheinen mir die verwendeten Konzepte zur Organisation/Trennung von generierten und manuellen Artefakten recht praktikabel, so dass ein leichter Einstieg in die Domain-Driven Entwicklung von Anwendungen möglich ist.

Mit Spring Roo können komplette CRUD-Webanwendungen inklusive Zugriff per REST erzeugt werden. Die umfangreiche Konfiguration, die dafür notwendig ist, wird einfach generiert. Das stellt natürlich eine enorme Erleichterung dar und die ersten Schritte zu einer minimalen Anwendung sind schnell erledigt. Wie aufwendig die manuelle Implementierung einer solchen einfachen Anwendung ist, musste ich bereits in diesem Posting feststellen.

July 6, 2009

REST-Anwendungen mit Spring 3.0

Die Interoperabilität zwischen heterogenen Softwaressystemen ist eine interessante Aufgabe. Zur Realisierung stehen heutzutage Web-Services über SOAP oder die Verwendung von REST zur Verfügung. Web-Services über SOAP sind unabhängig vom Übertragungsprotokoll und damit flexibler als REST, wobei HTTP verwendet wird. Außerdem sind für Web-Services ausführliche Definitionen der Schnittstellen (WSDL) und beim Austausch von Daten ein großer Anteil von Verwaltungsinformationen innerhalb der ausgetauschten XML-Nachrichten erforderlich. Das hat auch alles seine Vorteile, aber für eine einfache Anwendung, die lediglich Dienste/Informationen für andere Software zur Verfügung stellen möchte, scheint derzeit mit REST und der Verwendung des verbreiteten HTTP der pragmatischere Ansatz vorzuliegen.

In diesem Beitrag soll es aber nicht über die Unterschiede oder Vor- und Nachteile von Web-Services über SOAP gegenüber REST gehen, sondern die einfache Implementierung von Funktionalität über REST mit Spring 3.0 aufgezeigt werden. Anzumerken in diesem Zusammenhang sei noch, dass zum jetzigen Zeitpunkt Spring 3.0 noch nicht fertiggestellt ist und der Milestone 3 Verwendung findet. Allerdings sollte sich an der Anwendung nichts Grundlegendes ändern, da das Release von Spring 3.0 für das zweite Halbjahr 2009 angekündigt ist.

Zur Demonstration zeige ich in diesem und den folgenen Beiträgen die Implementierung einer rudimentären Webanwendung mit Sping MVC. Diese soll lediglich eine einfaches Ticketssystem abbilden, wobei lediglich Tickets angezeigt und die CRUD-Operationen unterstützt werden.

January 22, 2007

Web Service mit Java 6

Im neuen Java Release (Mustang) besteht die Möglichkeit ohne weitere Zusatzmittel mit Web Services zu arbeiten. Es ist sehr einfach einen solchen Service lokal zu testen. Lediglich die Klasse, die Services (Methoden/Funktionalität) bereitstellen soll, wird mit einigen Annotations versehen.

Um eine Klasse als Web Service zu kennzeichnen wird sie mit der Annotation javax.jws.WebService und Service Methoden mit javax.jws.WebMethod markiert. Außerdem muss der Web Service veröffentlicht werden. Hier hilft die Klasse javax.xml.ws.Endpoint, die eine statische Methode publish(String address, Object implementor) zur Verfügung stellt.

package webservicetest;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.ws.Endpoint;

@WebService
public class CalculatorService{

@WebMethod
public int duplicate(int value){
return value * 2;
}

public static void main(String[] args) {
Endpoint.publish("http://localhost:8080/Calculator", new CalculatorService());
}
}


Startet man die main Methode dieser Klasse, ist der Web Service unter der URL http://localhost:8080/Calculator so lange verfügbar bis das Programm terminiert. Als Test kann die URL http://localhost:8080/Calculator/rate?WSDL aufgerufen werden. Im Browser erscheint daraufhin eine Beschreibung des Services im WSDL Format.

Mehr Informationen und weitere Möglichkeiten finden sich in der Java 6 API.

January 5, 2007

Persistenz für Desktop Anwendungen mit JPA und JavaDB

Im neuen Java 6 Release wird eine Datenbank (Java DB) gleich mitgeliefert, daher liegt es nahe diese für Desktop Anwendungen zu benutzen. Außerdem wurde innerhalb des JSR 220 die sogenannte Java Persistence API (JPA) spezifiziert. Die Persistierung von Objekten wird dadurch transparenter und ist nicht mehr vom Persistenz Framework (z.B. Hibernate) abhängig. Zudem ist das objektrelationale Mapping deutlich einfacher, da es anhand von Annotations gesteuert wird.
Voraussetzungen

In dieser Beschreibung benutze ich die Eclipse Entwicklungsumgebung und Hibernate als Implementierung der JPA. Es werden folgende Hibernate Komponenten benötigt: Hibernate Core, Hibernate Annotations und Hibernate EntityManager. Außerdem ist ein installiertes Java 6 erforderlich.

Aus den verschiedenen Hibernate Komponenten werden folgende Bibliotheken benötigt, die am besten in den Ordner lib kopiert werden.

- lib
+ antlr-2.7.6.jar
+ asm-attrs.jar
+ asm.jar
+ c3p0-0.9.0.jar
+ cglib-2.1.3.jar
+ commons-collections-2.1.1.jar
+ commons-logging-1.0.4.jar
+ dom4j-1.6.1.jar
+ ejb3-persistence.jar
+ hibernate-annotations.jar
+ hibernate-entitymanager.jar
+ hibernate3.jar
+ javassist.jar
+ jboss-archive-browsing.jar
+ jta.jar
+ log4j-1.2.11.jar

Diese Bibliotheken müssen im Klassenpfad eingetragen sein. Außerdem ist es notwendig, die derby.jar ($JAVA_HOME/db/lib/) ebenfalls in den Klassenpfad aufzunehmen.

Konfiguration

Trotz Verwendung von Annotations für das objektrelationale Mapping ist eine Konfiguration mittels XML Datei erforderlich. Für JPA wird dazu im Verzeichnis etc/META-INF/ die Datei persistence.xml angelegt. Darin wird angegeben, welche JPA Implementierung genutzt wird. Außerdem werden Persistenz Framework spezifische Einstellungen vorgenommen. Da diese Datei, ebenso wie die Jar-Dateien, im Klassenpfad verfügbar sein muss, wird das etc Verzeichnis zu den Quellverzeichnissen (Source Folder) hinzugefügt.

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="hibernate">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="hibernate.connection.url" value="jdbc:derby:TestDatabase;create=true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
</properties>
</persistence-unit>
</persistence>

Jeder persistence-unit muss ein provider zugeordnet werden. Außerdem können weitere Providerspezifische Eigenschaften definiert werden.
Für das Beispiel mit Hibernate müssen Eigenschaften der Verbindung eingetragen werden. So z.B. der verwendete JDBC Treiber (hibernate.connection.driver_class) und die URL zur Datenbank (hibernate.connection.url). Die mitgelieferte JavaDB kann über jdbc:derby:$database erreicht werden. Beispielsweise wird durch die URL jdbc:derby:TestDatabase;create=true die Datenbank TestDatabase benutzt. Sollte diese nicht existieren, wird sie angelegt. Das Hibernate auch mit der JavaDB arbeiten kann, muss zudem der zu verwendende Dialekt eingestellt werden.

Diese drei Einstellungen sind notwendig, um mit der Hibernate auf JavaDB zu arbeiten. Es können aber noch viel mehr Einstellungen für Hibernate vorgenommen werden (siehe Hibernate Konfiguration).

Verwendung

Nach der Erstellung der Konfiguration können nun Objekte dauerhaft gespeichert und wieder gelesen werden. Dazu müssen die zu persistierenden Beans (bzw. POJOs) mit Annotations versehen werden. Alle Klassen, die persistiert werden sollen, erhalten die Annotation javax.persistence.Entity.

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Person {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "PERSON_ID")
private long id;

@Column(name="DNAME")
private String name;

private String firstName;

public String getFirstName() {
return this.firtsName;
}

public void setFirstName(final String firstName) {
this.firstName = firstName;
}

public long getId() {
return this.id;
}

public void setId(final long id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(final String name) {
this.name = name;
}
}


Daneben ist es notwendig, dass die Bean ein Attribut besitzt, über die das Objekt eindeutig identifiziert werden kann. Im Normalfall ist dieses Attribut vom Typ long. Dieser Identifier muss mit einer entsprechenden Annotation markiert werden (javax.persistence.Id). Weiterhin kann die Generierungsstrategie einer neuen Id festgelegt werden. Dazu wird die Annotation javax.persistence.GeneratedValue benutzt.
Neben der Deklaration der Id kann jeder Spalte der entsprechende Spaltenname in der Datenbank zugeordnet werden. Das geht über javax.persistence.Colum. Diese Annotation ist optional. Ist ein Attribut nicht damit versehen, wird einfach der Attributname als Spaltenname benutzt.
Dies sind nur ein paar wenige Einstellungen für eine JavaBean. Für weiterführende Informationen kann die API zu Rate gezogen werden.
Objekt speichern

Die zentrale Klasse zum speichern und laden von Objekten ist javax.persistence.EntityManager. Eine Instanz kann über javax.persistence.EntityManagerFactory erstellt werden.

final EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate");
final EntityManager em = emf.createEntityManager();

Nachdem der EntityManager verfügbar ist, wird eine javax.persistence.EntityTransaction benötigt. Diese Klasse ist zur Steuerung der Transaktionen verantwortlich. Will man ein Objekt in die Datenbank schreiben, braucht es eine offene Transaktion.

final EntityTransaction tx = em.getTransaction();
tx.begin();

Innerhalb dieser Transaktion kann nun ein Objekt persistiert werden.

final Person person = new Person();
person.setName("mrotzek");
person.setFirstName("michael");
em.persist(person);

Letztendlich muss die Transaktion noch geschlossen werden, um Änderungen wirklich in die Datenbank zu schreiben.

tx.commit();
em.close();
emf.close();

Objekt lesen

final EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate");
final EntityManager em = emf.createEntityManager();
final EntityTransaction tx = em.getTransaction();
tx.begin();
final List persons = em.createQuery("select p from Person p").getResultList();
System.out.println(persons.size() + " person(s) found");
for (final Object p : persons) {
final Person lPerson = (Person) p;
System.out.println(lPerson .getName()+", "+lPerson .getFirstName()+" : "+lPerson .getId());
}
tx.commit();
em.close();
emf.close();

Referenzen

Java DB
Using Java DB in Desktop Applications
Working with Derby and Hibernate
Java Persistence with Hibernate
The Java Persistence API
Standardizing Java Persistence with the EJB3 Java Persistence API

December 15, 2006

Neue Funktionen von Java 6

Anfang Dezember hat Sun Java 6 (Codename Mustang) veröffentlicht. Im Gegensatz zum Sprung von Java 1.4.2 auf Java 5 (Tiger) sind die Veränderungen zwischen Tiger und Mustang nicht so tiefgreifend. Trotzdem bietet das Mustang Release einige sinvolle Neuerungen.

Dazu gehört die intergrierte Web Service API, die die Erstellung eines solchen so einfach wie nie zuvor macht. Außerdem wurden einige Verbesserungen im Bereich Datenbankenzugriff vorgenommen. So wird JDBC 4.0 unterstützt. Daneben kommt Java 6 jetzt auch mit einer eigenen Datenbank (Java DB). Hier handelt es sich im wesentlichen um Apache Derby. Der Vorteil liegt darin, dass in einer Desktop Anwendung diese benutzt werden kann - es muss keine weitere Software eingebunden werden, um Daten persistent abzulegen.

Weiterhin soll die Performance bei Desktop Anwendungen verbessert worden sein, da einige Prüfungen nicht mehr zur Laufzeit sondern bereits beim Kompilieren durchgeführt werden. Auch das Look & Feel der Benutzeroberfläche (GUI) passt sich nun besser dem Betriebssystem an.

Ein sehr guter Überblick hier

April 25, 2006

Stripes Framework für Webanwendungen

Entwickler stehen zu Beginn einer Webanwendung oft vor dem Problem, sich für ein Präsentationsframework entscheiden zu müssen. Jeder der schon einmal mit Struts, JSF und Co. gekämpft hat, weiß wie schwer es ist, sich in diese einzuarbeiten.
Doch mit Stripes scheint eine Rettung in Sicht. Aus eigener Erfahrung kann ich behaupten, dass es einfach ist sich in dieses Framework einzuarbeiten, um schnell (sichtbare) Ergebnisse zu produzieren. Das fiel mir bei den bisherigen Platzhirschen nicht so leicht.

Dabei setzt Stripes stark auf Annotations von Java 5, was die Konfiguration bequem macht.
Einige Vorteile des Frameworks:

  • keine langen, unübersichtlichen Konfigurationsdateien (XML)

  • Zentrales Exceptionhandling

  • Mächtiges Validierung- und Typkonvertierungssystem

  • JUnit Testbarkeit

  • Wiederverwendbares Layout

  • Komplette Dokumentation; super Support


Für mich ein sehr gutes Framework, dass momentan sehr rege verbessert und erweitert wird.

March 19, 2006

Neue JUnit Version

JUnit gibt es nun in der Version 4.0. Das "revolutionär" neue an dieser Version ist, dass es mit Annotations von Java 1.5 arbeitet. Um einen JUnit Test zu schreiben, muss man nun nicht mehr von junit.framework.TestCase ableiten, sondern beschreibt das per Annotation. Die Testklassen sind dadurch auch deutlich kürzer und somit schneller zu erstellen.

Wie das im Detail geht, erfährt man hier in 10 Minuten.