© Lynx-Consulting GmbH | www.lynx.de1
Let’s talk about Java EE
Andreas König
Vortrag im Rahmen der Java-Usergroup Bielefeld
10.02.2016
© Lynx-Consulting GmbH | www.lynx.de2
AGENDA
Hands

on…
Java EE
spezifiziert
▪ Kurz angesprochen: Was verbirgt sich hinter Java EE?
Technische
Aspekte
▪ CDI, JPA & JSF — Bitte wie?
▪ Proof-of-Concept „Portfolio-Manager“
© Lynx-Consulting GmbH | www.lynx.de3
JAVA EE
SPEZIFIZIERT
© Lynx-Consulting GmbH | www.lynx.de4
▪ Spezifikation einer Softwarearchitektur
▪ Ermöglicht die Entwicklung transaktionsbasierter 

Web-Anwendungen & Middleware
▪ Erarbeitet durch den Java Community Process (JCP)
▪ Modulare Komponenten 

→ verteilte & mehrschichtige Anwendungen
▪ Laufzeitumgebung ist ein JEE-Application Server
JAVA EE IN FAKTEN
1.0 Java 2 Platform Enterprise Edition, v 1.0 Dezember 1999
1.2 Java 2 Platform Enterprise Edition, v 1.2 2000
1.2.1 Java 2 Platform Enterprise Edition, v 1.2.1 23. Mai 2000
1.3 Java 2 Platform Enterprise Edition, v 1.3 24. September 2001
1.4 Java 2 Platform Enterprise Edition, v 1.4 24. November 2003
5 Java Platform, Enterprise Edition, v 5 11. Mai 2006
6 Java Platform, Enterprise Edition, v 6 10. Dezember 2009
7 Java Platform, Enterprise Edition, v 7 12. Mai 2013
https://de.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition
© Lynx-Consulting GmbH | www.lynx.de5
JAVA EE 7 - SPEZIFIZIERT
JAVA	EE	PLATFORM	
JSR	342	-	Java	PlaBorm,	Enterprise	EdiCon	7	(Java	EE	7)	
WEB	APPLICATION	TECHNOLOGIES	
JSR	356	-	Java	API	for	WebSocket	
JSR	353	-	Java	API	for	JSON	Processing	
JSR	340	-	Java	Servlet	3.1	
JSR	344	-	JavaServer	Faces	2.2	
JSR	341	-	Expression	Language	3.0	
JSR	245	-	JavaServer	Pages	2.3	
JSR	052	-	Standard	Tag	Library	for	JavaServer	Pages	(JSTL)	1.2	
ENTERPRISE	APPLICATION	TECHNOLOGIES	
JSR	352	-	Batch	ApplicaCons	for	the	Java		
JSR	236	-	PlaBorm	Concurrency	UCliCes	for	Java	EE	1.0	
JSR	346	-	Contexts	and	Dependency	InjecCon	for	Java	1.1	
JSR	330	-	Dependency	InjecCon	for	Java	1.0	
JSR	349	-	Bean	ValidaCon	1.1	
JSR	345	-	Enterprise	JavaBeans	3.2	
JSR	318	-	Interceptors	1.2	
JSR	322	-	Java	EE	Connector	Architecture	1.7	
JSR	338	-	Java	Persistence	2.1	
JSR	250	-	Common	AnnotaCons	for	the	Java	PlaBorm	1.2	
JSR	343	-	Java	Message	Service	API	2.0		 	
JSR	907	-	Java	TransacCon	API	(JTA)	1.2	
JSR	919	-	JavaMail	1.5	
WEB	SERVICES	TECHNOLOGIES	
JSR	339	-	Java	API	for	RESTful	Web	Services	(JAX-RS)	2.0	
JSR	109	-	ImplemenCng	Enterprise	Web	Services	1.3	
JSR	224	-	Java	API	for	XML-Based	Web	Services	(JAX-WS)	2.2	
JSR	181	-	Web	Services	Metadata	for	the	Java	PlaBorm		 	
JSR	101	-	Java	API	for	XML-Based	RPC	(JAX-RPC)	1.1	(OpConal)	
JSR	067	-	Java	APIs	for	XML	Messaging	1.3	
JSR	093	-	Java	API	for	XML	Registries	(JAXR)	1.0	
MANAGEMENT	AND	SECURITY	TECHNOLOGIES	
JSR	196	-	Java	AuthenCcaCon	Service	Provider	Interface	for	
Containers	1.1	 	
JSR	115	-	Java	AuthorizaCon	Contract	for	Containers	1.5	
JSR	088	-	Java	EE	ApplicaCon	Deployment	1.2		(OpConal)	 	
JSR	077	-	J2EE	Management	1.1	 	
JSR	045	-	Debugging	Support	for	Other	Languages	1.0	
JAVA	EE-RELATED	SPECS	IN	JAVA	SE	
JSR	222	-	Java	Architecture	for	XML	Binding	(JAXB)	2.2	
JSR	206	-	Java	API	for	XML	Processing	(JAXP)	1.3	
JSR	221	-	Java	Database	ConnecCvity	4.0		
JSR	003	-	Java	Management	Extensions	(JMX)	2.0	
JSR	925	-	JavaBeans	AcCvaCon	Framework	(JAF)	1.1	
JSR	173	-	Streaming	API	for	XML	(StAX)	1.0
© Lynx-Consulting GmbH | www.lynx.de6
▪ Java EE Application Server bestehen u.a. aus
Frameworks/ Implementierungen, die den JSRs
entsprechen
▪ Am Beispiel WildFly 9 sind das u.a. folgende Frameworks:
▪ Undertow: WebServer / Servlet-Container
▪ Hibernate: Persistance (JPA) / ORM
▪ HornetQ: JMS-Queue
▪ Mojarra: JavaServer Faces (JSF)
▪ RESTEasy: REST-Services (JAX-RS)
▪ Apache CXF: WebServices (JAX-WS)
▪ Weld: Contexts & Dependency Injection
▪ Infinispan: Distributed Cache
▪ Arquillian: Test-Framework
APPLICATION SERVER
© Lynx-Consulting GmbH | www.lynx.de7
AUSGEWÄHLTE ASPEKTE
AUS DEM JAVA EE UMFELD
© Lynx-Consulting GmbH | www.lynx.de8
JAVA EE
MINIMIERTER STACK
▪ Nach „Vortragsrelevanz“ bereinigter Java EE - Stack
JPA JTA JMS
BeanValidation
Named Beans EJB
ServletCDI
Interceptors Annotations
JSF JAX-RS/WS
Angelehnt	an:	https://www.safaribooksonline.com/library/view/java-ee-6/9781449338329/ch01.html
© Lynx-Consulting GmbH | www.lynx.de9
CDI
Contexts & Dependency Injection
▪ Managed-/ Named-Beans
▪ Inject & Produce
▪ Verwendung aus JSF heraus
© Lynx-Consulting GmbH | www.lynx.de10
▪ CDI existiert seit Java EE 6
▪ Komponententechnologie
▪ Application Server erhält einen CDI-Container

z.B. WildFly → Weld
▪ Container erzeugt, verwaltet und stellt Java Beans bereit
▪ Konzept von Produzenten und Konsumenten

@Produces vs. @Inject // @Named
▪ Prinzip der „Inversion of Control“
▪ Verbessert u.a. die Erweiterungsfähigkeit & Wartbarkeit
der Anwendung durch Entkopplung der Komponenten
▪ Löst ab bzw. verallgemeinert das bestehende Modell von
Enterprise Java Beans (EJB) und JSF-Managed Beans
JAVA EE
CDI - CONTEXTS & DEPENDENCY INJECTION
Container
Instanz	1
Instanz	2
© Lynx-Consulting GmbH | www.lynx.de11
▪ Beispiel Logging
▪ Früher in jeder Klasse:
▪ Jetzt in jeder Klasse:
▪ Einmalig im CDI-Context definiert:
JAVA EE
CDI - INJECTIONS & PRODUCER
private static final Logger log =
LoggerFactory.getLogger(MyClass.getClass().getName());
@Inject
private Logger log;
@Produce
private Logger produceLogger(InjectionPoint ip) {
return LoggerFactory.getLogger(
ip.getMember().getDeclaringClass().getName());
}
© Lynx-Consulting GmbH | www.lynx.de12
▪ Beispiel CDI-Bean zur Verwendung in JSF
JAVA EE
CDI - BEANS
@Named
@SessionScoped
public class LoginUserController implements Serializable {
…
private User user;
public User getUser() { return user; }
…
public void login() { … };
public void logout() { … };
}
action="#{loginUserController.login}"
…
value="#{loginUserController.user.name}"
Zugriff innerhalb
einer .xhtml-Seite
Andere Scopes:
Request, View, Conversation, Flow, …
© Lynx-Consulting GmbH | www.lynx.de13
JPA
Java Persistence API
▪ Objekt-relationales Mapping
▪ u.a. JPQL vs. Criteria-API
© Lynx-Consulting GmbH | www.lynx.de14
▪ Dient der

Speicherung von Objekten in relationalen Datenbanken
▪ JPA verwendet im Hintergrund einen ORM 

(Objekt-relationalen Mapper) → z.B. Hibernate
▪ Aus Java @Entity-Beans können direkt die Datenbank-
Tabellen erzeugt werden
▪ Der EntityManager verwaltet den Zugriff auf die Datenbank
▪ ORM-Definitionen (u.a. auch die Angabe der zu
mappenden Entitäten) erfolgen in der persistence.xml
JAVA EE
JPA - JAVA PERSISTENCE API
© Lynx-Consulting GmbH | www.lynx.de15
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date einstellTs;
@NotNull
@Size(min = 3, max = 20)
private String name;
…
}
JAVA EE
JPA - ENTIÄTEN
id einstellTs name …
1 2015-12-18 10:00:00.000 andreas
2 2015-12-18 10:00:01.132 foo
…
Annotationen auch für
Validierungen im
Frontend:

BeanValidation
© Lynx-Consulting GmbH | www.lynx.de16
▪ Anfragen an den Entity-Manager (EM) lassen sich auf
mehrere Arten durchführen:
▪ Direkte Anfragen an den EM
▪ em.find(<Class>, PK) // em.persist(Entity)
▪ Named-Queries
▪ JPQL → SQL-ähnliche Anfragesprache
▪ Criteria API
▪ Fluent API mit Typ-Sicherheit
▪ Verlust der Lesbarkeit bei komplexeren Anfragen
▪ Generieren eines zusätzlichen Meta-Modells
▪ Native-Queries
▪ Wenn es nicht mehr weiter geht 😁
▪ Verwendung von Plain-SQL
JAVA EE
JPA - DATENBANKANFRAGEN
© Lynx-Consulting GmbH | www.lynx.de17
@Entity
@Table(indexes = { @Index(name = "ix_name", columnList = "name", unique = true) })
@NamedQueries({
/* Lese alle Benutzer. */
@NamedQuery(name = User.Q_READ_ALL_USERS, //
query = "SELECT u FROM User u" + //
" ORDER BY u.name") })
public class User implements Serializable {
…
public static final String Q_READ_ALL_USERS = „Q_READ_ALL_USERS";
…
}
public List<User> readUsers() {
TypedQuery<User> query =
em.createNamedQuery(
User.Q_READ_ALL_USERS, User.class);
return query.getResultList();
}
Hibernate:
select
user0_.id as id1_2_,
user0_.einstellTs as einstell2_2_,
user0_.lastTs as lastTs3_2_,
user0_.name as name4_2_,
user0_.pwHash as pwHash5_2_,
user0_.pwSalt as pwSalt6_2_,
user0_.role as role7_2_
from
User user0_
order by
user0_.name
JAVA EE
JPA - NAMED QUERIES
© Lynx-Consulting GmbH | www.lynx.de18
public List<StockOrder> readAllByUserId(long userId) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<StockOrder> cQuery = cb.createQuery(StockOrder.class);
Root<StockOrder> root = cQuery.from(StockOrder.class);
cQuery.select(root) //
.where(cb.equal(root.get(StockOrder_.user).get(User_.id), userId)) //
.orderBy(cb.desc(root.get(StockOrder_.kaufDatum)), cb.desc(root.get(StockOrder_.id)));
TypedQuery<StockOrder> query = em.createQuery(cQuery);
List<StockOrder> resultList = query.getResultList();
return resultList;
}
Hibernate:
select
stockorder0_.id as id1_1_,
stockorder0_.anzahl as anzahl2_1_,
stockorder0_.einstellTs as einstell3_1_,
stockorder0_.gebuehren as gebuehre4_1_,
stockorder0_.kaufDatum as kaufDatu5_1_,
stockorder0_.kurs as kurs6_1_,
stockorder0_.orderType as orderTyp7_1_,
stockorder0_.realerWert as realerWe8_1_,
stockorder0_.USER_ID as USER_ID9_1_
from
StockOrder stockorder0_
where
stockorder0_.USER_ID=2
order by
stockorder0_.kaufDatum desc,
stockorder0_.id desc
JAVA EE
JPA - CRITERIA API
@StaticMetamodel(StockOrder.class)
public class StockOrder_ {
public static volatile SingularAttribute<StockOrder, Long> id;
public static volatile SingularAttribute<StockOrder, User> user;
…
}
Metamodel
© Lynx-Consulting GmbH | www.lynx.de19
JAX-RS
REST-Services
▪ Erstellung eines „einfachen“ REST-Services
© Lynx-Consulting GmbH | www.lynx.de20
▪ REST → Representational State Transfer
▪ WebService-Alternative zu SOAP, WSDL, RPC
▪ Abstraktion der Struktur und des Verhaltens des WWW
▪ GET → Sicher, d.h. verändert nicht den Zustand
▪ PUT → Anlegen einer Resource
▪ POST → Ähnlich PUT & abbilden sonst. Operationen
▪ DELETE → Löschen einer Resource
JAVA EE
JAX-RS - REST-SERVICES
@ApplicationPath("/rest")
public class RestApplication extends Application {}
@GET
@Path("/from/{from}/to/{to}")
@Produces(MediaType.APPLICATION_JSON)
public List<…> getSomething(@PathParam("from") String fromDate,
@PathParam("to") String toDate) {
return resultList;
}
© Lynx-Consulting GmbH | www.lynx.de
JAVA EE
JAX-RS - REST-SERVICES
© Lynx-Consulting GmbH | www.lynx.de22
JSF
JavaServer Faces
▪ Lifecycle
▪ JSF inkl. AJAX
▪ Internationalisierung
▪ Primefaces
© Lynx-Consulting GmbH | www.lynx.de23
▪ JavaServer Faces (JSF) ist aktueller Standard für
dynamische Web-Oberflächen
▪ In Vorbereitung neben JSF für Java EE 8: MVC 1.0
▪ Asynchronous JavaScript and XML (AJAX)-Unterstützung
▪ JSF basiert auf dem Model-View-Controller (MVC)-Pattern
JAVA EE
JSF - JAVASERVER FACES
Faces Servlet
(Controller)
Managed Beans
(Model)
JSF Components
(View)
Browser
DB
Definiert in der web.xml
© Lynx-Consulting GmbH | www.lynx.de24
▪ Vom Request zur Response existiert ein mehrstufiger
Lebenszyklus
▪ Im Fall AJAX erfolgt ein Partial-View-Rendering
JAVA EE
JSF - LEBENSZYKLUS
Restore View
Apply Request
Parameters
Process
Validations
Update Model
Values
Invoke
Application
Render
Response
Request
Response
© Lynx-Consulting GmbH | www.lynx.de25
JAVA EE
JSF - MINIMALBEISPIEL MIT AJAX
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Simple Page</title>
<h:outputStylesheet library="css" name="style.css" />
</h:head>
<h:body>
<h:form>
<!-- Some Inputs to be AJAX-submitted -->
<h:inputText value="#{simpleBean.text}">
<f:ajax event="keyup" render=„outputId" />
</h:inputText>
<!-- Some Outputs refreshed by AJAX-Inputs above -->
<h:outputText id="outputId" value=„#{simpleBean.text}" />
</h:form>
</h:body>
</html>
@Named
@ViewScoped
public class SimpleBean
implements Serializable {
private static final long
serialVersionUID = 1L;
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
xhtml-Seite
Named Bean
© Lynx-Consulting GmbH | www.lynx.de26
JAVA EE
JSF - TEMPLATES
<html xmlns="http://www.w3.org/1999/xhtml"
…
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:body>
…
<!-- FOOTER -->
<ui:insert name="footer">
<h:outputText value="Footer-Text" />
</ui:insert>
</h:body>
</html>
<ui:composition template="/WEB-INF/templates/template.xhtml"
…
xmlns:ui=„http://xmlns.jcp.org/jsf/facelets">
…
<!-- FOOTER-REPLACEMENT -->
<ui:define name="footer">
<h:outputText value="Footer Replacement" />
</ui:define>
</h:body>
</ui:composition>
Template
Konkrete Seite
© Lynx-Consulting GmbH | www.lynx.de27
JAVA EE
JSF - COMPOSITE COMPONENTS
▪ Konstruktion von Komponenten, die mit einer Schnittstelle
ausgestattet werden können
▪ Mehrfache Verwendbarkeit
<html xmlns="http://www.w3.org/1999/xhtml"
…
xmlns:cc="http://xmlns.jcp.org/jsf/composite">
<cc:interface>
<cc:attribute name="percent" />
…
</cc:interface>
<cc:implementation>
…
<h:outputText value="#{cc.attrs.percent}">
<f:convertNumber type="percent"
maxFractionDigits="2"
minFractionDigits="2" />
</h:outputText>
…
</cc:implementation>
</html>
© Lynx-Consulting GmbH | www.lynx.de28
JAVA EE
INTERNATIONALISIERUNG
<h:outputFormat value="#{msg['txt.login.welcome']}"
rendered="#{not empty loginBean.user.name}">
<f:param value="#{loginBean.user.name}" />
</h:outputFormat>
txt.login.welcome=Hallo, {0}!
txt.login.welcome=Hello, {0}!
<application>
<locale-config>
<default-locale>de</default-locale>
</locale-config>
<resource-bundle>
<base-name>de.koenig.language.lang</base-name>
<var>msg</var>
</resource-bundle>
</application>
faces-config.xml
.xhtml
© Lynx-Consulting GmbH | www.lynx.de29
▪ Primefaces erweitert JSF um eine

umfangreiche Komponentenbibliothek!
▪ Input-/ Output-Elemente
▪ Buttons, Checkboxes, …
▪ Tabellen, Dialoge, Charts, Editoren, …
▪ Multimedia, File-Up-/ Download, …
▪ AJAX-Unterstützung
▪ Unterstützt „responsive Design“ mit HTML5 und CSS3
▪ Out-of-the-Box ansprechende Web-Oberfläche
▪ Freie und kommerzielle Designs
▪ Für mobile Geräte: Primefaces mobile
▪ Alternativen: RichFaces, IceFaces, …
JAVA EE
JSF - PRIMEFACES
© Lynx-Consulting GmbH | www.lynx.de30
JAVA EE
JSF - PRIMEFACES KOMPONENTEN
Screenshots	von	http://www.primefaces.org/showcase/
© Lynx-Consulting GmbH | www.lynx.de31
JAVA EE
JSF - PRIMEFACES KOMMERZIELLE DESIGNS
© Lynx-Consulting GmbH | www.lynx.de32
JAVA EE
JSF - PRIMEFACES KOMMERZIELLE DESIGNS
© Lynx-Consulting GmbH | www.lynx.de33
JAVA EE
JSF - PRIMEFACES KOMMERZIELLE DESIGNS
© Lynx-Consulting GmbH | www.lynx.de34
Weitere Patterns & Technologien
▪ Interceptoren
▪ Web-Filter
▪ Singletons
▪ Timer-Services
© Lynx-Consulting GmbH | www.lynx.de
▪ Interceptoren → @Interceptor // @InterceptorBinding
▪ Möglichkeit, Methodik voranzustellen und/ oder
nachzulagern, ohne die vorhandene Methode zu
ändern
▪ Anwendungsfälle:
▪ Zeitmessung oder Logging vor und nach einem
Methodenaufruf
▪ Transaktion auf einer Methode starten 

und beenden
▪ Tracking
35
JAVA EE
INTERCEPTOREN
Interceptor
Methode
© Lynx-Consulting GmbH | www.lynx.de36
JAVA EE
INTERCEPTOREN
@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface Logged {
}
@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {
…
@Inject
private Logger log;
@AroundInvoke
public Object aroundInvoke(InvocationContext ic) throws Exception {
Instant start = Instant.now();
Object output = null;
String clazz = ic.getMethod().getDeclaringClass().getSimpleName();
String method = ic.getMethod().getName();
log.info("ENTERING: {}.{} >> INPUT: {}", clazz, method, ic.getParameters());
try {
output = ic.proceed();
return output;
} finally {
Duration duration = Duration.between(start, Instant.now());
log.info("EXITING [{}ms]: {}.{} >> OUTPUT: {}", duration.toMillis(), clazz, method, output);
}
}
}
17:29:15,831
INFO
[LoggedInterceptor]
(default
task-11)
ENTERING:
UserRepo.updateLastTs
>>
INPUT:
[User
[id=2,
einstellTs=2015-12-10
11:30:31.757,
lastTs=Thu
Feb
04
17:29:15
CET
2016,
name=andreas,
pwHash=997d84d4c8d176a7f39fb91faec77c1f172d53fe96d0db08cf2d8722a
2aa29f7,
pwSalt=436edc92bd18bb9e387c4e4ac1cc6f3b,
role=USER,
orders.size=6]]
…
17:29:15,839
INFO
[LoggedInterceptor]
(default
task-11)
EXITING
[8ms]:
UserRepo.updateLastTs
>>
OUTPUT:
null
© Lynx-Consulting GmbH | www.lynx.de
▪ Web-Filter → @WebFilter
▪ Bildung von Filter-Ketten für Requests und Responses
▪ Bsp. Login-Filter, Monitoring, …
37
JAVA EE
WEB-FILTER
@WebFilter("/vip/*")
public class VipFilter implements Filter {
…
@Override public void init(FilterConfig fConfig) throws ServletException {}
@Override public void destroy() {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String loginURI = req.getContextPath();
// Ist ein Benutzer der Rolle USER angemeldet?
if (login.getUser() == null || !Role.USER.equals(login.getUser().getRole())) {
resp.sendRedirect(loginURI); return;
}
chain.doFilter(request, response);
}
}
© Lynx-Consulting GmbH | www.lynx.de38
▪ Singletons → @Singleton
▪ Fällt unter die Enterprise-Java-Beans (EJB)
▪ Nur eine Instanz pro Server
▪ Verwendung z.B. für einmalige Start-Up-Aktionen in
Kombination mit @Startup
▪ Bei verteilten Systemen läuft pro Server eine Instanz,
somit sind Synchronisationsmechanismen relevant
▪ Timer-Services → @Schedule
▪ Periodische Ausführung von Methodik
JAVA EE
WEITERE TECHNOLOGIEN
@Schedules({
@Schedule(dayOfMonth = "Last"),
@Schedule(dayOfWeek = "Fri"), hour = "23")})
private void doScheduledThings() { … }
© Lynx-Consulting GmbH | www.lynx.de39
HANDS-ON:
JAVA EE UND DIE GRÜNE WIESE
© Lynx-Consulting GmbH | www.lynx.de40
DEMONSTRATION
▪ Web-Portal
▪ Anzeige von DAX-Kursen (Yahoo-Finanz-API für Java)
▪ Login-Bereiche für die Rollen USER und ADMIN
▪ Verwaltung von Transaktionen auf den DAX

mit Gewinn-/ Verlust-Berechnung
▪ Technisch
▪ Server: WildFly 9.0.2.Final
▪ View: JSF mit Primefaces inkl. Templates
▪ Persistence: JPA mit Hibernate auf H2DB
▪ Schnittstellen: REST mit JSON & XML
▪ Sonstiges:
▪ CDI, Singletons, Timer-Services, Interceptors,
WebFilter, Internationalisierung, Maven
© Lynx-Consulting GmbH | www.lynx.de
DEMONSTRATION
© Lynx-Consulting GmbH | www.lynx.de42
DEMONSTRATION
42
© Lynx-Consulting GmbH | www.lynx.de43
VIELEN DANK FÜR
IHRE AUFMERKSAMKEIT
www.lynx.de
Lynx-Consulting GmbH | 33615 Bielefeld
Andreas König

Let's talk about Java EE

  • 1.
    © Lynx-Consulting GmbH| www.lynx.de1 Let’s talk about Java EE Andreas König Vortrag im Rahmen der Java-Usergroup Bielefeld 10.02.2016
  • 2.
    © Lynx-Consulting GmbH| www.lynx.de2 AGENDA Hands
 on… Java EE spezifiziert ▪ Kurz angesprochen: Was verbirgt sich hinter Java EE? Technische Aspekte ▪ CDI, JPA & JSF — Bitte wie? ▪ Proof-of-Concept „Portfolio-Manager“
  • 3.
    © Lynx-Consulting GmbH| www.lynx.de3 JAVA EE SPEZIFIZIERT
  • 4.
    © Lynx-Consulting GmbH| www.lynx.de4 ▪ Spezifikation einer Softwarearchitektur ▪ Ermöglicht die Entwicklung transaktionsbasierter 
 Web-Anwendungen & Middleware ▪ Erarbeitet durch den Java Community Process (JCP) ▪ Modulare Komponenten 
 → verteilte & mehrschichtige Anwendungen ▪ Laufzeitumgebung ist ein JEE-Application Server JAVA EE IN FAKTEN 1.0 Java 2 Platform Enterprise Edition, v 1.0 Dezember 1999 1.2 Java 2 Platform Enterprise Edition, v 1.2 2000 1.2.1 Java 2 Platform Enterprise Edition, v 1.2.1 23. Mai 2000 1.3 Java 2 Platform Enterprise Edition, v 1.3 24. September 2001 1.4 Java 2 Platform Enterprise Edition, v 1.4 24. November 2003 5 Java Platform, Enterprise Edition, v 5 11. Mai 2006 6 Java Platform, Enterprise Edition, v 6 10. Dezember 2009 7 Java Platform, Enterprise Edition, v 7 12. Mai 2013 https://de.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition
  • 5.
    © Lynx-Consulting GmbH| www.lynx.de5 JAVA EE 7 - SPEZIFIZIERT JAVA EE PLATFORM JSR 342 - Java PlaBorm, Enterprise EdiCon 7 (Java EE 7) WEB APPLICATION TECHNOLOGIES JSR 356 - Java API for WebSocket JSR 353 - Java API for JSON Processing JSR 340 - Java Servlet 3.1 JSR 344 - JavaServer Faces 2.2 JSR 341 - Expression Language 3.0 JSR 245 - JavaServer Pages 2.3 JSR 052 - Standard Tag Library for JavaServer Pages (JSTL) 1.2 ENTERPRISE APPLICATION TECHNOLOGIES JSR 352 - Batch ApplicaCons for the Java JSR 236 - PlaBorm Concurrency UCliCes for Java EE 1.0 JSR 346 - Contexts and Dependency InjecCon for Java 1.1 JSR 330 - Dependency InjecCon for Java 1.0 JSR 349 - Bean ValidaCon 1.1 JSR 345 - Enterprise JavaBeans 3.2 JSR 318 - Interceptors 1.2 JSR 322 - Java EE Connector Architecture 1.7 JSR 338 - Java Persistence 2.1 JSR 250 - Common AnnotaCons for the Java PlaBorm 1.2 JSR 343 - Java Message Service API 2.0 JSR 907 - Java TransacCon API (JTA) 1.2 JSR 919 - JavaMail 1.5 WEB SERVICES TECHNOLOGIES JSR 339 - Java API for RESTful Web Services (JAX-RS) 2.0 JSR 109 - ImplemenCng Enterprise Web Services 1.3 JSR 224 - Java API for XML-Based Web Services (JAX-WS) 2.2 JSR 181 - Web Services Metadata for the Java PlaBorm JSR 101 - Java API for XML-Based RPC (JAX-RPC) 1.1 (OpConal) JSR 067 - Java APIs for XML Messaging 1.3 JSR 093 - Java API for XML Registries (JAXR) 1.0 MANAGEMENT AND SECURITY TECHNOLOGIES JSR 196 - Java AuthenCcaCon Service Provider Interface for Containers 1.1 JSR 115 - Java AuthorizaCon Contract for Containers 1.5 JSR 088 - Java EE ApplicaCon Deployment 1.2 (OpConal) JSR 077 - J2EE Management 1.1 JSR 045 - Debugging Support for Other Languages 1.0 JAVA EE-RELATED SPECS IN JAVA SE JSR 222 - Java Architecture for XML Binding (JAXB) 2.2 JSR 206 - Java API for XML Processing (JAXP) 1.3 JSR 221 - Java Database ConnecCvity 4.0 JSR 003 - Java Management Extensions (JMX) 2.0 JSR 925 - JavaBeans AcCvaCon Framework (JAF) 1.1 JSR 173 - Streaming API for XML (StAX) 1.0
  • 6.
    © Lynx-Consulting GmbH| www.lynx.de6 ▪ Java EE Application Server bestehen u.a. aus Frameworks/ Implementierungen, die den JSRs entsprechen ▪ Am Beispiel WildFly 9 sind das u.a. folgende Frameworks: ▪ Undertow: WebServer / Servlet-Container ▪ Hibernate: Persistance (JPA) / ORM ▪ HornetQ: JMS-Queue ▪ Mojarra: JavaServer Faces (JSF) ▪ RESTEasy: REST-Services (JAX-RS) ▪ Apache CXF: WebServices (JAX-WS) ▪ Weld: Contexts & Dependency Injection ▪ Infinispan: Distributed Cache ▪ Arquillian: Test-Framework APPLICATION SERVER
  • 7.
    © Lynx-Consulting GmbH| www.lynx.de7 AUSGEWÄHLTE ASPEKTE AUS DEM JAVA EE UMFELD
  • 8.
    © Lynx-Consulting GmbH| www.lynx.de8 JAVA EE MINIMIERTER STACK ▪ Nach „Vortragsrelevanz“ bereinigter Java EE - Stack JPA JTA JMS BeanValidation Named Beans EJB ServletCDI Interceptors Annotations JSF JAX-RS/WS Angelehnt an: https://www.safaribooksonline.com/library/view/java-ee-6/9781449338329/ch01.html
  • 9.
    © Lynx-Consulting GmbH| www.lynx.de9 CDI Contexts & Dependency Injection ▪ Managed-/ Named-Beans ▪ Inject & Produce ▪ Verwendung aus JSF heraus
  • 10.
    © Lynx-Consulting GmbH| www.lynx.de10 ▪ CDI existiert seit Java EE 6 ▪ Komponententechnologie ▪ Application Server erhält einen CDI-Container
 z.B. WildFly → Weld ▪ Container erzeugt, verwaltet und stellt Java Beans bereit ▪ Konzept von Produzenten und Konsumenten
 @Produces vs. @Inject // @Named ▪ Prinzip der „Inversion of Control“ ▪ Verbessert u.a. die Erweiterungsfähigkeit & Wartbarkeit der Anwendung durch Entkopplung der Komponenten ▪ Löst ab bzw. verallgemeinert das bestehende Modell von Enterprise Java Beans (EJB) und JSF-Managed Beans JAVA EE CDI - CONTEXTS & DEPENDENCY INJECTION Container Instanz 1 Instanz 2
  • 11.
    © Lynx-Consulting GmbH| www.lynx.de11 ▪ Beispiel Logging ▪ Früher in jeder Klasse: ▪ Jetzt in jeder Klasse: ▪ Einmalig im CDI-Context definiert: JAVA EE CDI - INJECTIONS & PRODUCER private static final Logger log = LoggerFactory.getLogger(MyClass.getClass().getName()); @Inject private Logger log; @Produce private Logger produceLogger(InjectionPoint ip) { return LoggerFactory.getLogger( ip.getMember().getDeclaringClass().getName()); }
  • 12.
    © Lynx-Consulting GmbH| www.lynx.de12 ▪ Beispiel CDI-Bean zur Verwendung in JSF JAVA EE CDI - BEANS @Named @SessionScoped public class LoginUserController implements Serializable { … private User user; public User getUser() { return user; } … public void login() { … }; public void logout() { … }; } action="#{loginUserController.login}" … value="#{loginUserController.user.name}" Zugriff innerhalb einer .xhtml-Seite Andere Scopes: Request, View, Conversation, Flow, …
  • 13.
    © Lynx-Consulting GmbH| www.lynx.de13 JPA Java Persistence API ▪ Objekt-relationales Mapping ▪ u.a. JPQL vs. Criteria-API
  • 14.
    © Lynx-Consulting GmbH| www.lynx.de14 ▪ Dient der
 Speicherung von Objekten in relationalen Datenbanken ▪ JPA verwendet im Hintergrund einen ORM 
 (Objekt-relationalen Mapper) → z.B. Hibernate ▪ Aus Java @Entity-Beans können direkt die Datenbank- Tabellen erzeugt werden ▪ Der EntityManager verwaltet den Zugriff auf die Datenbank ▪ ORM-Definitionen (u.a. auch die Angabe der zu mappenden Entitäten) erfolgen in der persistence.xml JAVA EE JPA - JAVA PERSISTENCE API
  • 15.
    © Lynx-Consulting GmbH| www.lynx.de15 @Entity public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @NotNull @Temporal(TemporalType.TIMESTAMP) private Date einstellTs; @NotNull @Size(min = 3, max = 20) private String name; … } JAVA EE JPA - ENTIÄTEN id einstellTs name … 1 2015-12-18 10:00:00.000 andreas 2 2015-12-18 10:00:01.132 foo … Annotationen auch für Validierungen im Frontend:
 BeanValidation
  • 16.
    © Lynx-Consulting GmbH| www.lynx.de16 ▪ Anfragen an den Entity-Manager (EM) lassen sich auf mehrere Arten durchführen: ▪ Direkte Anfragen an den EM ▪ em.find(<Class>, PK) // em.persist(Entity) ▪ Named-Queries ▪ JPQL → SQL-ähnliche Anfragesprache ▪ Criteria API ▪ Fluent API mit Typ-Sicherheit ▪ Verlust der Lesbarkeit bei komplexeren Anfragen ▪ Generieren eines zusätzlichen Meta-Modells ▪ Native-Queries ▪ Wenn es nicht mehr weiter geht 😁 ▪ Verwendung von Plain-SQL JAVA EE JPA - DATENBANKANFRAGEN
  • 17.
    © Lynx-Consulting GmbH| www.lynx.de17 @Entity @Table(indexes = { @Index(name = "ix_name", columnList = "name", unique = true) }) @NamedQueries({ /* Lese alle Benutzer. */ @NamedQuery(name = User.Q_READ_ALL_USERS, // query = "SELECT u FROM User u" + // " ORDER BY u.name") }) public class User implements Serializable { … public static final String Q_READ_ALL_USERS = „Q_READ_ALL_USERS"; … } public List<User> readUsers() { TypedQuery<User> query = em.createNamedQuery( User.Q_READ_ALL_USERS, User.class); return query.getResultList(); } Hibernate: select user0_.id as id1_2_, user0_.einstellTs as einstell2_2_, user0_.lastTs as lastTs3_2_, user0_.name as name4_2_, user0_.pwHash as pwHash5_2_, user0_.pwSalt as pwSalt6_2_, user0_.role as role7_2_ from User user0_ order by user0_.name JAVA EE JPA - NAMED QUERIES
  • 18.
    © Lynx-Consulting GmbH| www.lynx.de18 public List<StockOrder> readAllByUserId(long userId) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<StockOrder> cQuery = cb.createQuery(StockOrder.class); Root<StockOrder> root = cQuery.from(StockOrder.class); cQuery.select(root) // .where(cb.equal(root.get(StockOrder_.user).get(User_.id), userId)) // .orderBy(cb.desc(root.get(StockOrder_.kaufDatum)), cb.desc(root.get(StockOrder_.id))); TypedQuery<StockOrder> query = em.createQuery(cQuery); List<StockOrder> resultList = query.getResultList(); return resultList; } Hibernate: select stockorder0_.id as id1_1_, stockorder0_.anzahl as anzahl2_1_, stockorder0_.einstellTs as einstell3_1_, stockorder0_.gebuehren as gebuehre4_1_, stockorder0_.kaufDatum as kaufDatu5_1_, stockorder0_.kurs as kurs6_1_, stockorder0_.orderType as orderTyp7_1_, stockorder0_.realerWert as realerWe8_1_, stockorder0_.USER_ID as USER_ID9_1_ from StockOrder stockorder0_ where stockorder0_.USER_ID=2 order by stockorder0_.kaufDatum desc, stockorder0_.id desc JAVA EE JPA - CRITERIA API @StaticMetamodel(StockOrder.class) public class StockOrder_ { public static volatile SingularAttribute<StockOrder, Long> id; public static volatile SingularAttribute<StockOrder, User> user; … } Metamodel
  • 19.
    © Lynx-Consulting GmbH| www.lynx.de19 JAX-RS REST-Services ▪ Erstellung eines „einfachen“ REST-Services
  • 20.
    © Lynx-Consulting GmbH| www.lynx.de20 ▪ REST → Representational State Transfer ▪ WebService-Alternative zu SOAP, WSDL, RPC ▪ Abstraktion der Struktur und des Verhaltens des WWW ▪ GET → Sicher, d.h. verändert nicht den Zustand ▪ PUT → Anlegen einer Resource ▪ POST → Ähnlich PUT & abbilden sonst. Operationen ▪ DELETE → Löschen einer Resource JAVA EE JAX-RS - REST-SERVICES @ApplicationPath("/rest") public class RestApplication extends Application {} @GET @Path("/from/{from}/to/{to}") @Produces(MediaType.APPLICATION_JSON) public List<…> getSomething(@PathParam("from") String fromDate, @PathParam("to") String toDate) { return resultList; }
  • 21.
    © Lynx-Consulting GmbH| www.lynx.de JAVA EE JAX-RS - REST-SERVICES
  • 22.
    © Lynx-Consulting GmbH| www.lynx.de22 JSF JavaServer Faces ▪ Lifecycle ▪ JSF inkl. AJAX ▪ Internationalisierung ▪ Primefaces
  • 23.
    © Lynx-Consulting GmbH| www.lynx.de23 ▪ JavaServer Faces (JSF) ist aktueller Standard für dynamische Web-Oberflächen ▪ In Vorbereitung neben JSF für Java EE 8: MVC 1.0 ▪ Asynchronous JavaScript and XML (AJAX)-Unterstützung ▪ JSF basiert auf dem Model-View-Controller (MVC)-Pattern JAVA EE JSF - JAVASERVER FACES Faces Servlet (Controller) Managed Beans (Model) JSF Components (View) Browser DB Definiert in der web.xml
  • 24.
    © Lynx-Consulting GmbH| www.lynx.de24 ▪ Vom Request zur Response existiert ein mehrstufiger Lebenszyklus ▪ Im Fall AJAX erfolgt ein Partial-View-Rendering JAVA EE JSF - LEBENSZYKLUS Restore View Apply Request Parameters Process Validations Update Model Values Invoke Application Render Response Request Response
  • 25.
    © Lynx-Consulting GmbH| www.lynx.de25 JAVA EE JSF - MINIMALBEISPIEL MIT AJAX <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <title>Simple Page</title> <h:outputStylesheet library="css" name="style.css" /> </h:head> <h:body> <h:form> <!-- Some Inputs to be AJAX-submitted --> <h:inputText value="#{simpleBean.text}"> <f:ajax event="keyup" render=„outputId" /> </h:inputText> <!-- Some Outputs refreshed by AJAX-Inputs above --> <h:outputText id="outputId" value=„#{simpleBean.text}" /> </h:form> </h:body> </html> @Named @ViewScoped public class SimpleBean implements Serializable { private static final long serialVersionUID = 1L; private String text; public String getText() { return text; } public void setText(String text) { this.text = text; } } xhtml-Seite Named Bean
  • 26.
    © Lynx-Consulting GmbH| www.lynx.de26 JAVA EE JSF - TEMPLATES <html xmlns="http://www.w3.org/1999/xhtml" … xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> <h:body> … <!-- FOOTER --> <ui:insert name="footer"> <h:outputText value="Footer-Text" /> </ui:insert> </h:body> </html> <ui:composition template="/WEB-INF/templates/template.xhtml" … xmlns:ui=„http://xmlns.jcp.org/jsf/facelets"> … <!-- FOOTER-REPLACEMENT --> <ui:define name="footer"> <h:outputText value="Footer Replacement" /> </ui:define> </h:body> </ui:composition> Template Konkrete Seite
  • 27.
    © Lynx-Consulting GmbH| www.lynx.de27 JAVA EE JSF - COMPOSITE COMPONENTS ▪ Konstruktion von Komponenten, die mit einer Schnittstelle ausgestattet werden können ▪ Mehrfache Verwendbarkeit <html xmlns="http://www.w3.org/1999/xhtml" … xmlns:cc="http://xmlns.jcp.org/jsf/composite"> <cc:interface> <cc:attribute name="percent" /> … </cc:interface> <cc:implementation> … <h:outputText value="#{cc.attrs.percent}"> <f:convertNumber type="percent" maxFractionDigits="2" minFractionDigits="2" /> </h:outputText> … </cc:implementation> </html>
  • 28.
    © Lynx-Consulting GmbH| www.lynx.de28 JAVA EE INTERNATIONALISIERUNG <h:outputFormat value="#{msg['txt.login.welcome']}" rendered="#{not empty loginBean.user.name}"> <f:param value="#{loginBean.user.name}" /> </h:outputFormat> txt.login.welcome=Hallo, {0}! txt.login.welcome=Hello, {0}! <application> <locale-config> <default-locale>de</default-locale> </locale-config> <resource-bundle> <base-name>de.koenig.language.lang</base-name> <var>msg</var> </resource-bundle> </application> faces-config.xml .xhtml
  • 29.
    © Lynx-Consulting GmbH| www.lynx.de29 ▪ Primefaces erweitert JSF um eine
 umfangreiche Komponentenbibliothek! ▪ Input-/ Output-Elemente ▪ Buttons, Checkboxes, … ▪ Tabellen, Dialoge, Charts, Editoren, … ▪ Multimedia, File-Up-/ Download, … ▪ AJAX-Unterstützung ▪ Unterstützt „responsive Design“ mit HTML5 und CSS3 ▪ Out-of-the-Box ansprechende Web-Oberfläche ▪ Freie und kommerzielle Designs ▪ Für mobile Geräte: Primefaces mobile ▪ Alternativen: RichFaces, IceFaces, … JAVA EE JSF - PRIMEFACES
  • 30.
    © Lynx-Consulting GmbH| www.lynx.de30 JAVA EE JSF - PRIMEFACES KOMPONENTEN Screenshots von http://www.primefaces.org/showcase/
  • 31.
    © Lynx-Consulting GmbH| www.lynx.de31 JAVA EE JSF - PRIMEFACES KOMMERZIELLE DESIGNS
  • 32.
    © Lynx-Consulting GmbH| www.lynx.de32 JAVA EE JSF - PRIMEFACES KOMMERZIELLE DESIGNS
  • 33.
    © Lynx-Consulting GmbH| www.lynx.de33 JAVA EE JSF - PRIMEFACES KOMMERZIELLE DESIGNS
  • 34.
    © Lynx-Consulting GmbH| www.lynx.de34 Weitere Patterns & Technologien ▪ Interceptoren ▪ Web-Filter ▪ Singletons ▪ Timer-Services
  • 35.
    © Lynx-Consulting GmbH| www.lynx.de ▪ Interceptoren → @Interceptor // @InterceptorBinding ▪ Möglichkeit, Methodik voranzustellen und/ oder nachzulagern, ohne die vorhandene Methode zu ändern ▪ Anwendungsfälle: ▪ Zeitmessung oder Logging vor und nach einem Methodenaufruf ▪ Transaktion auf einer Methode starten 
 und beenden ▪ Tracking 35 JAVA EE INTERCEPTOREN Interceptor Methode
  • 36.
    © Lynx-Consulting GmbH| www.lynx.de36 JAVA EE INTERCEPTOREN @Inherited @InterceptorBinding @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.TYPE }) public @interface Logged { } @Logged @Interceptor public class LoggedInterceptor implements Serializable { … @Inject private Logger log; @AroundInvoke public Object aroundInvoke(InvocationContext ic) throws Exception { Instant start = Instant.now(); Object output = null; String clazz = ic.getMethod().getDeclaringClass().getSimpleName(); String method = ic.getMethod().getName(); log.info("ENTERING: {}.{} >> INPUT: {}", clazz, method, ic.getParameters()); try { output = ic.proceed(); return output; } finally { Duration duration = Duration.between(start, Instant.now()); log.info("EXITING [{}ms]: {}.{} >> OUTPUT: {}", duration.toMillis(), clazz, method, output); } } } 17:29:15,831 INFO [LoggedInterceptor] (default task-11) ENTERING: UserRepo.updateLastTs >> INPUT: [User [id=2, einstellTs=2015-12-10 11:30:31.757, lastTs=Thu Feb 04 17:29:15 CET 2016, name=andreas, pwHash=997d84d4c8d176a7f39fb91faec77c1f172d53fe96d0db08cf2d8722a 2aa29f7, pwSalt=436edc92bd18bb9e387c4e4ac1cc6f3b, role=USER, orders.size=6]] … 17:29:15,839 INFO [LoggedInterceptor] (default task-11) EXITING [8ms]: UserRepo.updateLastTs >> OUTPUT: null
  • 37.
    © Lynx-Consulting GmbH| www.lynx.de ▪ Web-Filter → @WebFilter ▪ Bildung von Filter-Ketten für Requests und Responses ▪ Bsp. Login-Filter, Monitoring, … 37 JAVA EE WEB-FILTER @WebFilter("/vip/*") public class VipFilter implements Filter { … @Override public void init(FilterConfig fConfig) throws ServletException {} @Override public void destroy() {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; String loginURI = req.getContextPath(); // Ist ein Benutzer der Rolle USER angemeldet? if (login.getUser() == null || !Role.USER.equals(login.getUser().getRole())) { resp.sendRedirect(loginURI); return; } chain.doFilter(request, response); } }
  • 38.
    © Lynx-Consulting GmbH| www.lynx.de38 ▪ Singletons → @Singleton ▪ Fällt unter die Enterprise-Java-Beans (EJB) ▪ Nur eine Instanz pro Server ▪ Verwendung z.B. für einmalige Start-Up-Aktionen in Kombination mit @Startup ▪ Bei verteilten Systemen läuft pro Server eine Instanz, somit sind Synchronisationsmechanismen relevant ▪ Timer-Services → @Schedule ▪ Periodische Ausführung von Methodik JAVA EE WEITERE TECHNOLOGIEN @Schedules({ @Schedule(dayOfMonth = "Last"), @Schedule(dayOfWeek = "Fri"), hour = "23")}) private void doScheduledThings() { … }
  • 39.
    © Lynx-Consulting GmbH| www.lynx.de39 HANDS-ON: JAVA EE UND DIE GRÜNE WIESE
  • 40.
    © Lynx-Consulting GmbH| www.lynx.de40 DEMONSTRATION ▪ Web-Portal ▪ Anzeige von DAX-Kursen (Yahoo-Finanz-API für Java) ▪ Login-Bereiche für die Rollen USER und ADMIN ▪ Verwaltung von Transaktionen auf den DAX
 mit Gewinn-/ Verlust-Berechnung ▪ Technisch ▪ Server: WildFly 9.0.2.Final ▪ View: JSF mit Primefaces inkl. Templates ▪ Persistence: JPA mit Hibernate auf H2DB ▪ Schnittstellen: REST mit JSON & XML ▪ Sonstiges: ▪ CDI, Singletons, Timer-Services, Interceptors, WebFilter, Internationalisierung, Maven
  • 41.
    © Lynx-Consulting GmbH| www.lynx.de DEMONSTRATION
  • 42.
    © Lynx-Consulting GmbH| www.lynx.de42 DEMONSTRATION 42
  • 43.
    © Lynx-Consulting GmbH| www.lynx.de43 VIELEN DANK FÜR IHRE AUFMERKSAMKEIT www.lynx.de Lynx-Consulting GmbH | 33615 Bielefeld Andreas König