Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE...

38
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

Transcript of Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE...

Page 1: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

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

Page 2: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

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

Page 3: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Page 4: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Page 5: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Page 6: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Page 7: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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 C

lien

t S

erv

er

Page 8: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

Page 9: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

V

Page 10: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

@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;

}

Page 11: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

@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<Locale, String> texts;

}

Page 12: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

Page 13: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

@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;

}

Page 14: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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<Timezone> {

}

Clie

nt

Serv

er

C

@Produces({ "application/json", "text/xml" })

@Consumes({ "application/json", "text/xml" })

public abstract class

DefaultRestEndpoint<ENTITY extends HasId> {

< … 500 Zeilen Generics, Reflection, JPA Metamodel,

JavaDoc … Einblick auf der nächsten Folie … >

}

Page 15: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 15

Blick durch Schlüsselloch in DefaultRestEndpoint

Clie

nt

Serv

er

C

public abstract class DefaultRestEndpoint<ENTITY extends HasId> {

@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<ENTITY extends HasId> {

@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<ENTITY extends HasId> {

….

@POST

@Path("/qbe")

public List<ENTITY> 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();

}

}

Page 16: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 16

Object Graph Traversal

Clie

nt

Serv

er

C

@Stateless

@Path("/sighting")

public class SightingEndpoint extends DefaultRestEndpoint<Sighting> {

@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<ENTITY extends HasId>

{

@GET

@JsonView(ListView.class)

public Response listAll() {

}

public class Sighting extends AbstractEntity {

@JsonView(Extended.class)

public String getSightingMemo() {

return sightingMemo;

}

}

Page 17: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

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"}

Page 18: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 18

Erweiterungspunkt: Custom Serialisierer

Clie

nt

Serv

er

C

public class DateTimeZoneDeserializer extends

JsonDeserializer<DateTimeZone> {

@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<DateTimeZone> {

@Override

public void serialize(DateTimeZone value, JsonGenerator jgen,

SerializerProvider provider) throws IOException {

jgen.writeString(value.getID());

}

}

Page 19: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

C

@Provider

public class CustomObjectMapper implements ContextResolver<ObjectMapper> {

@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

Page 20: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 20

Exception Handler

Clie

nt

Serv

er

C

@Provider

public class EntityNotFoundExceptionMapper implements

ExceptionMapper<EntityNotFoundException> {

@Inject

private Localizer localizer;

@Override

public Response toResponse(EntityNotFoundException exception) {

Map<String, String> responseObj = new HashMap<String, String>();

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 + "}";

}

}

}

Page 21: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 21

Validierung von Daten

Clie

nt

Serv

er

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<ConstraintViolationException> {

@Override

public Response toResponse(ConstraintViolationException exception) {

Map<String, Object> responseObj = new HashMap<String, Object>();

for (ConstraintViolation<?> violation : exception.getConstraintViolations()) {

// … < 40 Zeilen Code > …

}

return Response.status(Response.Status.BAD_REQUEST).entity(responseObj)

.build();

}

P

Page 22: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

C

JEE kann REST!

P

Page 23: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

HTML Single Page Apps – aber bitte strukturiert und mit Modularisierung

V

M

Page 24: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 24

Beispiel: Eingabefelder mit Label und Eingabefeld

HTML im View

Clie

nt

Serv

er

CSS-Frameworks wie Bootstrap erlauben ein schlankes HTML

V <form class="form-horizontal" >

<fieldset>

<legend>Zeitzone bearbeiten</legend>

<div class="row-fluid">

<div class="control-group">

<label class="control-label" for="bezeichnung">Name</label>

<div class="controls">

<input type="text" id="timezoneName" class="input-large" />

</div>

</div>

</div>

</fieldset>

</form>

Page 25: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 25

Umgesetzt mit KnockoutJS

View-Model

Clie

nt

Serv

er

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();

}

<!-- index.html -->

<ul class="nav" data-bind="foreach: menu.folders">

<li data-bind="css: { active: $data.link ==

$parent.menu.folder() }, attr: {id: $data.link} "><a

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

$data.link}"></a></li>

</ul> M

Page 26: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

Bidirektionales Binding

V

<!-- vessel.js -->

self.deleteLanguage = function(language) {

self.vessel().vesselName.remove(language);

};

M

<!-- vessel.html -->

<a class="btn btn-small“ data-bind="click:

$parents[2].deleteLanguage">

<i class="icon-trash"></i>

</a>

Page 27: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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)

Clie

nt

Serv

er

Modularisierung der Anwendung (Model) mit requireJS

V

<!-- vessel.js -->

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' ]

},…

<!– index.html -->

<script data-main="js/main"

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

Page 28: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 28

Modularisierung (Usecases)

Clie

nt

Serv

er

Modularisierung der Use-Cases

V

M

übergreifende Module

Bibliotheken

ein Template pro Use Case

eine JS Datei pro Use Case

Page 29: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

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);

});

});

Page 30: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

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

Page 31: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

HTML + JavaScript können strukturiert werden!

V

M

C

Page 32: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© msg systems ag, 4. April 2013 HTML5 und JEE REST / BedCon 2013 / Alexander Schwartz 32

Automatisiertes Testen

Clie

nt

Serv

er

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

Page 33: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

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

Page 34: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

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");

});

});

Page 35: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

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

Page 36: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

Ein Browser-Reload lässt die Tests erneut laufen

C

V

M

Page 37: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

© 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

Clie

nt

Serv

er

JEE REST Backend ergänzt sich mit HTML/JS Frontend

V

M

C

B

P

Page 38: Schnelle und leichtgewichtige Anwendungsentwicklung mit ... · • JAX-RS 1.0/2.0 als Teil von JEE 6/7 • Kommunikation via REST/JSON ideal für JavasScript • Persistenz via JPA

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