Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Schnelle und leichtgewichtige Anwendungsentwicklung mit HTML5 und JEE/REST

Schnelle und leichtgewichtige Anwendungsentwicklung mit HTML5 und JEE/REST

Über die Jahre haben sich HTML und JEE stark gewandelt. Mit den heute vorliegenden Versionen ist eine effektive und effiziente Anwendungsentwicklung möglich.
Bei HTML wurde aus einer reinen Seitenbeschreibungssprache durch JavaScript, DOM und CSS eine vollwertige Client-Plattform, die nicht nur auf Effekte und Komponenten wie z.B. jQuery und jQuery UI setzt, sondern auch zusehends durch MV*-Frameworks strukturiert wird.
In der letzten Iteration brachte JEE neben den vorher schon starken Bereichen wie z.B. Persistenz zum ersten Mal Context Dependency Injection (CDI), Validierung von Werten mittels Annotationen (Bean Validation) und REST-Schnittstellen (JAX-RS) mit.
Im Laufe des Vortrags wird Schritt für Schritt eine strukturiere HTML5-Anwendung entwickelt, mit der ein leichtgewichtiges JEE REST-Backend mit Persistenz und Validierung alle seine Vorteile ausspielen kann. Außerdem wird gezeigt, wie diese Anwendung inkrementell erweitert und automatisiert getestet werden kann.

Alexander Schwartz

April 04, 2013
Tweet

More Decks by Alexander Schwartz

Other Decks in Technology

Transcript

  1. Schnelle und leichtgewichtige Anwendungsentwicklung
    mit HTML5 und JEE REST
    Alexander Schwartz
    Berlin Expert Days (BedCon) 2013 / 4. April 2013
    1 © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz

    View full-size slide

  2. 2
    Was ich vorhabe
    1. Worum es geht
    2. Fachlicher Einstieg in das Beispiel
    3. JEE Stack für REST auf dem Server
    4. HTTP + JavaScript Stack auf dem Client
    5. Testen der Anwendung
    6. Detaillierung Server-Tests
    7. Detaillierung Client-Tests
    8. Zusammenfassung
    © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz

    View full-size slide

  3. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    3
    Worum es hier geht
    • HTML als Seitenbeschreibung
    • CSS für ansprechendes (responsive) Design
    • Widget z.B. via jQueryUI + Plugins
    • Clientlogik via JavaScript
    • Strukturierung mit Javascript MV*-Frameworks
    (z. B. KnockoutJS)
    • Modularisierung und Nachladen von Resourcen
    (z. B. requireJS)
    • JAX-RS 1.0/2.0 als Teil von JEE 6/7
    • Kommunikation via REST/JSON ideal für JavasScript
    • Persistenz via JPA
    • Validierung von Daten mit Bean Validation
    • CDI für Erweiterungspunkte
    • Integration in Enterprise IT dank vieler Java-Bibliotheken
    Browser als
    Client-Plattform
    JEE REST für
    serverseitige
    Services
    HTML+JavaScript und JEE+REST als Plattform

    View full-size slide

  4. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    4
    Wer ich bin
    Alexander Schwartz
    Lead IT Consultant im GB Travel und Logistics
    10 Jahre Java
    7 Jahre PL/SQL
    7 Jahre
    Absatzfinanzierung
    3,5 Jahre Direktbank
    1 Frau
    2 Kinder
    216 gefundene
    Geocaches

    View full-size slide

  5. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    5
    Mein Sponsor und Arbeitgeber
    1980 gegründet
    mehr als 4000 Kollegen
    8 Branchen
    540 Mio € Umsatz 2012
    22 Länder
    16 deutsche
    Standorte
    msg systems ag

    View full-size slide

  6. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    6
    User Story:
    „Nutzer möchte die Sichtung eines Schiffes
    erfassen, um später sehen zu können, ob auch
    andere dieses Schiff gesehen haben.
    Hierzu erfasst er Schifftstyp, Datum,
    Zeitzone und eine Notiz.“
    Die heutige Aufgabe
    Online-Datenbank für (Raum-)Schiffsichtungen
    Garantiert kein
    Bezug zu
    einem
    Kundenprojekt!
    https://github.com/
    ahus1/rest-
    samples

    View full-size slide

  7. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    7
    Unser Wegweiser
    • Darstellung User-Interface
    • Interaktion mit dem Nutzer
    V
    View
    • Datenhaltung im Client
    • Bindung an den View
    M
    View Model
    • Kommunikation zwischen Server/Client
    • Besteht aus server- und clientseitigem Teil
    C
    Communication
    • Fachliche Business-Logik
    • Greift auf Persistenz zu
    B
    Business Services
    • Datenhaltung und Persistenz
    P
    Persistence
    Eine klare Schichtentrennung hilft als Wegweiser durch die Architektur
    Client Server

    View full-size slide

  8. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    8
    Was es im Inneren zusammenhält
    Sichtung
    Schiffstyp
    Zeitzone
    Domain-Model für Struktur hilft Fachabteilung und Entwicklern
    M
    C
    P
    Client Server

    View full-size slide

  9. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    9
    Wie´s für den Kunden aussieht
    Mockups klären früh das Maskenlayout und verringern Nacharbeiten
    P
    Client Server
    V

    View full-size slide

  10. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    10
    • IDs werden automatisch generiert
    • Validierung über Bean-Validation
    • Basis-Klasse AbstractEntity für Optimistic Locking
    Los geht‘s – die erste Entität
    Standard-JPA-Entität für „Zeitzone“
    P
    Client Server
    @Entity
    public class Timezone extends AbstractEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long timezoneId;
    @NotEmpty
    private String timezoneName;

    }
    @MappedSuperclass
    public class AbstractEntity {
    @Version
    private Integer version;

    }

    View full-size slide

  11. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    11
    • Übersetzbares Element als Entität Translation
    • CascadeType.ALL für gemeinsame Speicherung
    • Orphan Removal für Housekeeping
    • Translation enthält eine Map mit Übersetzungen
    Entität mit Übersetzung
    Komplexe Entität „Schiffstyp“
    P
    Client Server
    @Entity
    public class Vessel extends AbstractEntity {
    @Id
    @GeneratedValue
    (strategy = GenerationType.IDENTITY)
    private Long vesselId;
    @OneToOne(fetch = FetchType.EAGER,
    cascade = CascadeType.ALL,
    orphanRemoval = true)
    @JoinColumn(name = "vesselName")
    private Translation vesselName;

    }
    @Entity
    public class Translation extends AbstractEntity {
    @Id
    @GeneratedValue
    (strategy = GenerationType.IDENTITY)
    private Long translationId;
    @ElementCollection
    @CollectionTable(name = "Text", joinColumns =
    @JoinColumn(name = "translationId"))
    @MapKeyColumn(name = "textLanguage")
    @Column(name = "textString")
    private Map texts;

    }

    View full-size slide

  12. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    12
    Vorsicht beim (Daten-Model) Bau
    Abbildung fachlicher Datentypen auf technische Datentypen
    Fachlich Java JSON JavaScript
    Zeichenkette String String String
    Ganzzahl Long Number Number
    Dezimalbruch BigDecimal String * String *
    Datum LocalDateTime String ** String **
    * JavaScript Number-Type unterstützt nur Fließkommazahlen, aber keine Dezimalzahlen. Es
    können dadurch Rundungsdifferenzen auftreten, die fachlich nicht gewünscht sind. Daher
    Fallback auf String.
    ** „Standard“ bei JSON ist für Datumsangaben Sekunden seit 1970 und Zeit UTC.
    LocalDateTime lässt sich so nicht abbilden; Date in JavaScript wird in der Zeitzone des
    Browser dargestellt => keine Kontrolle durch Anwendung möglich möglich. Daher Fallback auf
    Datum als String im ISO-Format
    M
    C
    P
    Client Server

    View full-size slide

  13. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    13
    • ManyToOne-Relation für Selectbox Vessel – ohne Cascade!
    • Joda-Elemente für Zeiten; usertype für Joda-Persistenz
    Datum in JPA
    Komplexe Entität „Sichtung“
    P
    Client Server
    @Entity
    public class Sighting extends AbstractEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long sightingId;
    private String sightingMemo;
    @ManyToOne
    @JoinColumn(name = "vesselId")
    private Vessel vessel;
    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTimeZoneAsString")
    private DateTimeZone sightingTimezone;
    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    private LocalDateTime sightingDate;

    }

    View full-size slide

  14. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    14
    • DefaultRestEndpoint liefert CRUD Funktionalität
    • Genug „Platz“ im Endpoint für spezifische Funktionalität
    (z.B. Aufruf von Business Services)
    • Sicherstellung „Don‘t Repeat Yourself“
    Erster REST Endpoint
    Java-Generics sind gut!
    @Stateless
    @Path("/timezone")
    public class TimezoneEndpoint extends DefaultRestEndpoint {
    }
    Client Server
    C
    @Produces({ "application/json", "text/xml" })
    @Consumes({ "application/json", "text/xml" })
    public abstract class
    DefaultRestEndpoint {
    < … 500 Zeilen Generics, Reflection, JPA Metamodel,
    JavaDoc … Einblick auf der nächsten Folie … >
    }

    View full-size slide

  15. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    15
    Blick durch Schlüsselloch in DefaultRestEndpoint
    Client Server
    C
    public abstract class DefaultRestEndpoint {

    @GET
    @Path("/{id:.+}")
    public Response findById(@PathParam("id") String id, @Context Request
    request) {
    ENTITY result = em.find(getEntityClass(), constructPK(id));
    if (result == null) {
    throw new EntityNotFoundException();
    }
    pullByJsonView(result, getExtendedView());
    return Response.ok(result).build();
    }

    public abstract class DefaultRestEndpoint {

    @POST
    @Path("")
    public Response add(ENTITY entity) {
    bindReadOnlyEntities(entity);
    em.persist(entity);
    em.flush();
    UriBuilder locationBuilder = uriInfo.getBaseUriBuilder();
    locationBuilder.path(this.getClass());
    URI childLocation = locationBuilder.path("{id}").build(entity.getId());
    return Response.status(Response.Status.CREATED).location(childLocation)
    .build();
    }

    public abstract class DefaultRestEndpoint {
    ….
    @POST
    @Path("/qbe")
    public List queryByExample(ENTITY entity) {
    Session session = (Session) em.getDelegate();
    Example example = Example.create(entity).enableLike(MatchMode.ANYWHERE)
    .ignoreCase();
    Criteria criteria = session.createCriteria(entity.getClass()).add(example);
    addSubCriteria(criteria, entity);
    if (criteria.list().isEmpty()) {
    return null;
    } else {
    pullByJsonView(criteria.list(), getExtendedView());
    return criteria.list();
    }
    }

    View full-size slide

  16. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    16
    Object Graph Traversal
    Client Server
    C
    @Stateless
    @Path("/sighting")
    public class SightingEndpoint extends DefaultRestEndpoint {
    @Override
    protected Class> getExtendedView() {
    return Sighting.Extended.class;
    }
    @Override
    @GET
    @Path("/{id:.+}")
    @JsonView(Sighting.Extended.class)
    public Response findById(@PathParam("id") String id,
    @Context Request request) {
    return super.findById(id, request);
    }

    }
    Mit @JsonView-Annotationen kann die Sichtbarkeit eingeschränkt werden
    public abstract class
    DefaultRestEndpoint
    {
    @GET
    @JsonView(ListView.class)
    public Response listAll() {

    }
    public class Sighting extends AbstractEntity {

    @JsonView(Extended.class)
    public String getSightingMemo() {
    return sightingMemo;
    }

    }

    View full-size slide

  17. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    17
    • Fachliche Überlegung: kein sightingMemo in der Übersicht notwendig
    • Technische Überlegung: kein version in der Übersicht notwendig
    • ABER: @JsonView gibt‘s nur bei Jackson (nicht JEE Standard)
    Object Graph Traversal Output
    Client Server
    C
    GET http://localhost:8080/rest-samples/rest/sighting
    [{"sightingId":1,
    "vessel":{"vesselId":1,"vesselName":"Klingonischer Jäger"},
    "sightingTimezone":"Europe/Berlin",
    "sightingDate":"2013-04-11T11:00:00.000"},
    {"sightingId":2,
    "vessel":{"vesselId":1,"vesselName":"Klingonischer Jäger"},
    "sightingTimezone":"Europe/London",
    "sightingDate":"2013-04-11T22:00:00.000"}]
    In der Liste sind weniger Attribute angezeigt, in der Einzelansicht mehr
    GET http://localhost:8080/rest-samples/rest/sighting/-1
    {"version":1,
    "sightingId":1,
    "sightingMemo":"unheimlich!",
    "vessel":{"version":0,"vesselId":-1,"vesselName":"Klingonischer Jäger"},
    "sightingTimezone":"Europe/Berlin",
    "sightingDate":"2013-04-11T11:00:00.000"}

    View full-size slide

  18. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    18
    Erweiterungspunkt: Custom Serialisierer
    Client Server
    C
    public class DateTimeZoneDeserializer extends
    JsonDeserializer {
    @Override
    public DateTimeZone deserialize(JsonParser jparse,
    DeserializationContext context) throws IOException {
    String text = jparse.getText();
    if (text == null || text.trim().length() == 0) {
    return null;
    } else {
    return DateTimeZone.forID(text);
    }
    }
    }
    DateTimeZone serialisieren (da kein Standardtyp)
    public class DateTimeZoneSerializer extends JsonSerializer {
    @Override
    public void serialize(DateTimeZone value, JsonGenerator jgen,
    SerializerProvider provider) throws IOException {
    jgen.writeString(value.getID());
    }
    }

    View full-size slide

  19. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    19
    • Serialiserer für DateTimeZone und BigDecimal registrieren
    Erweiterungspunkt: Custom Serialisierer
    Client Server
    C
    @Provider
    public class CustomObjectMapper implements ContextResolver {
    @Override
    public ObjectMapper getContext(Class> type) {
    final ObjectMapper result = new ObjectMapper();
    SimpleModule module = new SimpleModule(getClass().getName(), new Version(1,
    0, 0, null))
    .addDeserializer(BigDecimal.class, new BigDecimalAmountDeserializer())
    .addSerializer(BigDecimal.class, new BigDecimalAmountSerializer())
    .addDeserializer(DateTimeZone.class, new DateTimeZoneDeserializer())
    .addSerializer(DateTimeZone.class, new DateTimeZoneSerializer());
    result.registerModule(module);
    result.configure(Feature.WRITE_DATES_AS_TIMESTAMPS, false);
    return result;
    }
    }
    Registrieren der Serialisierer / De-Serialisierer

    View full-size slide

  20. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    20
    Exception Handler
    Client Server
    C
    @Provider
    public class EntityNotFoundExceptionMapper implements
    ExceptionMapper {
    @Inject
    private Localizer localizer;
    @Override
    public Response toResponse(EntityNotFoundException exception) {
    Map responseObj = new HashMap();
    responseObj.put("general", localizer.localize("error.entityNotFound"));
    return Response.status(Response.Status.NOT_FOUND).entity(responseObj)
    .build();
    }
    }
    Für jede Exception kann (muss) ein eigener Handler definiert werden
    public class Localizer {
    @Inject
    private HttpServletRequest httpServletRequest;
    public String localize(String key) {
    try {
    ResourceBundle rb = ResourceBundle.getBundle("messages",
    httpServletRequest.getLocale());
    return rb.getString(key);
    } catch (MissingResourceException e) {
    return "{" + key + "}";
    }
    }
    }

    View full-size slide

  21. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    21
    Validierung von Daten
    Client Server
    C
    @Entity
    public class Sighting extends AbstractEntity {

    @NotNull
    @Size(min = 2, message = "{sighting.memo.minLength}")
    private String sightingMemo;

    }
    Bean Validation plus Exception-Handler
    #ValidationMessages_de.properties
    sighting.memo.minLength=Muss mindestens {min} Zeichen lang sein
    @Entity
    public class Sighting extends AbstractEntity {

    @NotNull
    @Size(min = 2, message = "{sighting.memo.minLength}")
    private String sightingMemo;

    }
    @Provider
    public class ConstraintViolationExceptionMapper implements
    ExceptionMapper {
    @Override
    public Response toResponse(ConstraintViolationException exception) {
    Map responseObj = new HashMap();
    for (ConstraintViolation> violation : exception.getConstraintViolations()) {
    // … < 40 Zeilen Code > …
    }
    return Response.status(Response.Status.BAD_REQUEST).entity(responseObj)
    .build();
    }
    P

    View full-size slide

  22. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    22
    • Querschnittsfunktionen lassen sich einfach von domänenspezifischen
    Elementen trennen
    • APIs und Erweiterungspunkte für spezifische Implementierungen sind
    vorhanden
    • JSON Serialisierung ist nicht in JEE 6.0 standardisiert
    • Durch Generics, JPA Metamodel und Reflection gelingt es, das DRY
    Prinzip durchzuhalten
    JEE Zwischenfazit
    Client Server
    C
    JEE kann REST!
    P

    View full-size slide

  23. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    23
    Anforderungen:
    • HTML für den View
    • View-Model für Datenhaltung
    • Bi-direktionales Datenbinding View / View-Model
    • Modularisierung von JavaScript-Bibliotheken, aber auch Templates
    und JavaScript-Code für Usecases der Anwendung
    • Stateful-URLs innerhalb der Anwendung; Vor-/Zurück-Navigation
    Einstieg HTML
    Client Server
    HTML Single Page Apps – aber bitte strukturiert und mit Modularisierung
    V
    M

    View full-size slide

  24. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    24
    Beispiel: Eingabefelder mit Label und Eingabefeld
    HTML im View
    Client Server
    CSS-Frameworks wie Bootstrap erlauben ein schlankes HTML
    V


    Zeitzone bearbeiten


    Name







    View full-size slide

  25. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    25
    Umgesetzt mit KnockoutJS
    View-Model
    Client Server
    Ein Menü anzeigen – Trennung View vom View Model
    V
    // menu.js
    var Menu = function() {
    // Data
    var self = this;
    self.folders = ko.observableArray([ {
    name : 'Schiffstypen',
    link : '#/vessel/main'
    }, {
    name : 'Sichtungen',
    link : '#/sighting/main'
    }, {
    name : 'Zeitzonen',
    link : '#/timezone/main'
    } ]);
    self.folder = ko.observable();
    }


    data-bind="text: $data.name, attr: {href:
    $data.link}">

    M

    View full-size slide

  26. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    26
    Eine Texteingabe im Input-Feld aktualisiert das Modell – eine Änderung
    im Modell aktualisiert den View
    View-Model
    Client Server
    Bidirektionales Binding
    V

    self.deleteLanguage = function(language) {
    self.vessel().vesselName.remove(language);
    };
    M

    $parents[2].deleteLanguage">


    View full-size slide

  27. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    27
    • Jedes Modul erhält einen „Header“ mit Abhängigkeiten
    • Für 3rd-Party-Bibliotheken werden im der Startprozedur
    Abhängigkeiten definiert
    • requireJS sorgt für parallelen Download der JS-Module
    Modularisierung (Model)
    Client Server
    Modularisierung der Anwendung (Model) mit requireJS
    V

    define(
    [ 'knockout', 'jquery', 'mapping', 'hasher',
    'crossroads', 'menu' ],
    function(ko, $, mapping, hasher, crossroads,
    menu) {
    // logik…
    });
    M
    //main.js
    require.config({
    shim : {
    jquery : {
    exports : "jQuery"
    },
    knockout : {
    deps : [ 'jquery' ]
    },
    'knockout.validation' : {
    deps : [ 'knockout' ]
    },…

    src="js/libs/require.js">

    View full-size slide

  28. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    28
    Modularisierung (Usecases)
    Client Server
    Modularisierung der Use-Cases
    V
    M
    übergreifende Module
    Bibliotheken
    ein Template pro Use Case
    eine JS Datei pro Use Case

    View full-size slide

  29. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    29
    • HTML5 unterstützt das „History“ API, bei dem URLs sich ändern
    können, auch wenn die Seite gleich bleibt
    • Zusatzinformationen zu einer Seite können per JavaScript in der
    Browser-Historie abgelegt werden
    Ohne History-API:
    • Workaround: URL hinter dem Hash-Tag
    http://localhost:8080/rest-samples/#/vessel/edit/1
    http://localhost:8080/rest-samples/#/vessel/main
    http://localhost:8080/rest-samples/#/timezone/edit/1
    • Unterstützt z.B. durch Crossroads.js
    Stateful URLs
    Client Server
    URLs für den direkten Einstieg – und Vor-/Zurücknavigation
    V
    crossroads.addRoute(/vessel\/edit\/(.+)$/, function(id) {
    $.get("rest/vessel/" + id, function(data) {
    self.vessel(mapping.fromJS(toViewModel(data)));
    self.vesselList(null);
    });
    });

    View full-size slide

  30. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    30
    • Laden eines Elements
    • Das Model kann ggf. für
    den View punktuell
    transformiert werden,
    z.B. HashMap als Array
    REST-Anbindung in JavaScript
    Client Server
    Das Model im Backend kann weitgehend beibehalten werden
    $.get("rest/vessel/" + id, function(data) {
    self.vessel(mapping.fromJS(toViewModel(data)));
    self.vesselList(null);
    });
    function toViewModel(data) {
    data = jQuery.extend(true, {}, data);
    var text = [];
    $.each(data.vesselName, function(key, value) {
    text.push({
    textLanguage : key,
    textString : value
    });
    });
    data.vesselName = text;
    return data;
    }
    C
    M
    M

    View full-size slide

  31. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    31
    • Querschnittsfunktionen lassen sich einfach von domänenspezifischen
    Elementen trennen
    • APIs und Erweiterungspunkte für spezifische Implementierungen sind
    vorhanden
    • Die Zahl der Bibliotheken und APIs ist deutlich größer als im JEE
    Bereich
    • Ist der Rahmen vorbereitet, können einfach neue Use Cases
    dazuentwickelt werden (je eine JS + HTML Datei pro Use Case)
    • Code-Änderungen sind nach einem Browser-Refresh sofort sichtbar
    HTML/JS Zwischenfazit
    Client Server
    HTML + JavaScript können strukturiert werden!
    V
    M
    C

    View full-size slide

  32. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    32
    Automatisiertes Testen
    Client Server
    Verschiedene Testframeworks decken verschiedene Bereiche ab
    V
    M
    C
    B
    P
    Jasmine,
    Sinon
    Selenium
    IDE
    Selenium
    RC
    Junit
    Arquillian
    Arquillian
    +
    REST-
    assured
    Mock?
    Mock?
    geringe Komplexität
    hohe Komplexität

    View full-size slide

  33. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    33
    Arquillian:
    • Automatisiertes
    Deployment von
    Teilen der
    Server-Anwendung
    (ggf. ergänzt um
    Mock-Komponenten)
    REST-assured:
    • Testen der
    REST-services
    mit Fluent API
    Arquillian + REST assured
    Client Server
    Test-Anwendungen automatisiert packen und laufen lassen
    @RunWith(Arquillian.class)
    public class MesseEndpointTest {
    @Deployment
    public static WebArchive createArchiveAndDeploy() {
    WebArchive war = ShrinkWrap.create(WebArchive.class,
    "arquillian-rest-demo.war");
    war.addPackages(…);
    war.addAsLibraries(…);
    return war;
    }
    @Test
    public void testReturnFilledList() throws Exception {
    Response r = given().log().all()
    .contentType(ContentType.JSON).expect()
    .body("[0].meBezeichnung", equalTo("Vessel 1"))
    .statusCode(Status.OK.getStatusCode()).when()
    .get("/rest-samples/rest/vessel");
    assertThat("only one element exists",
    r.body().jsonPath().getList("").size(), equalTo(1));
    }
    B
    P
    C

    View full-size slide

  34. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    34
    Kleine Tests:
    • Unit-Tests für JavaScript-Code-Bibliotheken
    • Ergänzt durch HTML-Fragmente
    • DOM-Interaktion möglich durch jQuery Integration
    Große Tests:
    • Tests der vollständigen Use Cases
    Jasmine BDD Testframework
    Client Server
    Anforderungen beschreiben und Tests automatisieren auf dem Client
    V
    M
    describe("Manage Vessels", function() {
    it("shows a list of two vessels at the start",
    function() {
    expect($("#vesselList")).toBeVisible();
    expect($("#vesselList > tbody > tr")[0]).toContainHtml("Vessel 1");
    expect($("#vesselList > tbody > tr")[1]).toContainHtml("Vessel 2");
    });
    });

    View full-size slide

  35. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    35
    Frontend-Entwickler ist unabhängig vom Backend – und kann selber
    Testen
    Sinon.JS für Mocks
    Client Server
    Backend kann via JavaScript simuliert werden
    describe("Manage Vessels", function() {
    beforeEach(function() {
    server = sinon.fakeServer.create();
    server.respondWith("GET", "rest/vessel", [ 200, {
    "Content-Type" : "application/json"
    }, vesselList ]);
    server.respondWith("DELETE", "rest/vessel/1", [ 204, null, "" ]);
    server.respondWith("GET", "rest/vessel/1", [ 200, {
    "Content-Type" : "application/json"
    }, vessel ]);
    afterEach(function() {
    // disable fake server
    server.restore();
    });
    );
    C

    View full-size slide

  36. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    36
    • 7 Tests
    • 760 ms
    Gesamtlaufzeit
    • Cross-Browser
    • Unabhängig vom
    Backend
    • Dokumentation
    aus fachlicher
    Sicht
    • Beliebige
    Schachtelung
    Jasmine ist schnell und einfach
    Client Server
    Ein Browser-Reload lässt die Tests erneut laufen
    C
    V
    M

    View full-size slide

  37. © msg systems ag, 4. April 2013
    HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz
    37
    • Backend und Frontend können fachliche Komponenten und
    technische Komponenten von einander getrennt werden
    • Steht der Rahmen, so können Entwickler an unabhängig an
    verschiedenen Use Cases arbeiten
    • Steht der Rahmen, so können Entwickler mit geringen
    Vorkenntnissen in die Entwicklung einsteigen
    • Frontend und Backend können separat entwickelt werden
    • HTML+JS bietet schnelle Turnaround-Zeiten in der Entwicklung
    • JEE REST bietet Integration in Enterprise IT und stabile
    Laufzeitumgebung
    • Sowohl Frontend als auch Backend können einfach skalieren
    • Durch neue HTML5 Features wie Local Storage und kann die
    Skalierung weiter erhöht werden
    Zusammenfassung
    Client Server
    JEE REST Backend ergänzt sich mit HTML/JS Frontend
    V
    M
    C
    B
    P

    View full-size slide

  38. www.msg-systems.com
    Vielen Dank für Ihre Aufmerksamkeit
    msg systems ag
    Mergenthalerallee 73 - 75
    65760 Eschborn
    Telefon: +49 (171) 5 62 57 67
    E-Mail: [email protected]
    www.msg-systems.com
    38 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz © msg systems ag, 4. April 2013

    View full-size slide