Motiviert durch den Beitrag über die drei Design Prinzipien setzen wir jetzt eine solche REST Architektur mit Wildfly um.

Voraussetzung dafür sind folgende drei Komponenten:

Ziel unserer Anwendung ist es, eine einfache Benutzerliste zu verwalten. Das implementieren wir in mehreren Schritten:

  • das Modell
  • der Endpunkt
  • das Datenzugriffs-Objekt
  • Context- und Dependency Injection

das Modell

Starten wir mit dem Modell, und legen ein Model-Package an. Im Eclipse klicken wir also unseren src Ordner und legen ein Paket com.example.hello.model an. Unser Datenmodell besteht nur aus einfachen Benutzern mit einem Primärschlüssel, Vorname und Nachname. Unsere Modell-Entitäten sind POJOs, also ganz normale Java Objekte.

Unsere User Klasse1 sieht so aus:

public class User {
    public int id;
    public String name;
    public String email;
}       

der Endpunkt

UserEndpoint erstellen Um ein REST Service zu erstellen, benutzen wir die bereits installierten JBoss Tools. Zuerst erstellen wir ein weiteres Paket com.example.hello.rest und klicken dorthin und wählen New→JAX‑RS Resource. Wir wählen mit dem Browse… Button als Entity unsere User - Klasse, akzeptieren als Name UserEndpoint und selektieren die Methoden findById und listAll. Nach Next und Finish erhalten wir schon eine fast fertige Implementierung des REST Endpunktes. Die Annotationen @Produces und @Consumes geben an, welchen Datentype der Endpunkt liefert bzw. konsumiert, hier ersetzen wie die generierten Strings durch MediaType.APPLICATION_JSON.

Damit haben wir das Gerüst für unser erstes REST Service fertig. Was wir noch einbauen müssen, ist das Holen der Daten aus der Datenbank.

das Datenzugriffs-Objekt

Nachdem wir ein neues Paket com.example.hello.dao erstellt haben, legen wir dort mit New→Interface eine allgemeine Definition für ein DataAccessObject an:

package com.example.com.hello.dao;

import java.util.List;

public interface DataAccessObject<T extends Object> {
    T findById(int id);
    List<T> listAll();
}

Die Methode findById hat hierbei die Aufgabe, einen User bei gegebenem Primärschlüssel zu finden, während listAll alle Benutzer zurückgibt.

Damit können wir unseren UserEndpoint fertig implementieren, indem wir dieses DataAccessObjekt verwenden:

package com.example.hello.rest;

import java.util.List;
// ... 

import javax.inject.Inject;
// ...

@RequestScoped
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserEndpoint {
    @Inject
    DataAccessObject<User> userDao;

    @GET
    @Path("/{id:[0-9][0-9]*}")
    public Response findById(@PathParam("id") final Long id) {
        User user = userDao.findById(id.intValue());
        return user != null ?
            Response.ok(user).build() :
            Response.status(Status.NOT_FOUND).build();
    }

    @GET
    public List<User> listAll(@QueryParam("start") final Integer startPosition,
            @QueryParam("max") final Integer maxResult) {
        return userDao.listAll();
    }
}

Noch haben wir nichts darüber gesagt, wie unser userDao die User findet und trotzdem ist unser UserEndpoint fertig gestellt. Der Beitrag über Dependency Injection erklärt die @Inject Annotation.

Context- und Dependency Injection

Nachdem wir mit der rechten Maustaste auf unser Projekt geklickt haben, wählen wir Configure→Add CDI (Context and Dependency Injection) support… und File→New…→Other… und geben im Suchfeld beans.xml ein. Dies erzeugt eine leere beans.xml Datei im WEB-INF Verzeichnis, die Voraussetzung für das CDI ist2.

Um das ganze auszuprobieren, fügen wir unsere Testdatenbank hinzu und starten die Anwendung wie vorher beschrieben.


  1. aus Gründen der Übersichtlichkeit verzichte ich hier auf das Information Hiding

  2. Siehe JEE - Tutorial: An application that uses CDI must have a file named beans.xml. The file can be completely empty (it has content only in certain limited situations), but it must be present. For a web application, the beans.xml file must be in the WEB-INF directory.