Java Web Aufbau – Tag 10 von 10
Von Elyndra Valen, Senior Developer bei Java Fleet Systems Consulting

🗺️ Deine Position im Kurs
| Tag | Thema | Status |
|---|---|---|
| 1 | Filter im Webcontainer | ✅ Abgeschlossen |
| 2 | Listener im Webcontainer | ✅ Abgeschlossen |
| 3 | Authentifizierung über Datenbank | ✅ Abgeschlossen |
| 4 | Container-Managed Security & Jakarta Security API | ✅ Abgeschlossen |
| 5 | Custom Tags & Tag Handler (SimpleTag) | ✅ Abgeschlossen |
| 6 | Custom Tag Handler mit BodyTagSupport | ✅ Abgeschlossen |
| 7 | JPA vs JDBC – Konfiguration & Provider | ✅ Abgeschlossen |
| 8 | JPA Relationen (1): @OneToOne & @ManyToOne | ✅ Abgeschlossen |
| 9 | JPA Relationen (2): @OneToMany & @ManyToMany | ✅ Abgeschlossen |
| → 10 | JSF Überblick – Component-Based UI | 👉 DU BIST HIER! |
Modul: Java Web Aufbau
Gesamt-Dauer: 10 Arbeitstage (je 8 Stunden)
Dauer heute: 8 Stunden
Dein Ziel: JSF professionell einsetzen mit Templates, Navigation, Validation und AJAX
📋 Voraussetzungen für diesen Tag
Du brauchst:
- ✅ Tag 9 abgeschlossen! (JakartaServer Faces Basics mit @Named Beans)
- ✅ Funktionierendes JSF-Projekt von Tag 9
- ✅ Entweder:
- Apache Tomcat 10.x (Tag9-JSF-Tomcat) ODER
- Payara Server 6.x (Tag9-JSF-Payara)
- ✅ Verständnis von @Named Beans, @Transactional, JSF Facelets
Tag 9 verpasst?
Spring zurück! Tag 10 baut direkt auf Tag 9 auf. Ohne JSF-Basics wird heute schwer.
Hinweis: Alle heutigen Beispiele funktionieren auf beiden Servern (Tomcat UND Payara)!
⚡ Das Wichtigste in 30 Sekunden
Was du gestern gelernt hast (Tag 9):
- JSF Facelets (.xhtml)
- @Named Beans + @Transactional
- OrderController + OrderDAO
- Einfaches JSF DataTable
- JSF Basics verstanden
Was du heute lernst:
- Facelets Templates für wiederverwendbare Layouts
- Navigation zwischen JSF-Pages
- Validation (Built-in + Bean Validation)
- AJAX für Partial Page Updates
- Best Practices für Production
Warum ist das wichtig? Gestern hast du JSF-Grundlagen gelernt. Heute machst du daraus production-ready Enterprise-Anwendungen mit professionellen Features.
👋 Willkommen zu Tag 10 – Dem Finale!
Hi! 👋
Elyndra hier. Letzter Tag des Java Web Aufbau Kurses! 🎉
Recap Tag 9:
Gestern hast du deine erste JSF-Anwendung gebaut:
java
// OrderDAO mit @Named + @Transactional
@Named
@RequestScoped
@Transactional
public class OrderDAO {
@PersistenceContext
private EntityManager em;
public Order createOrder(...) { ... }
}
// OrderController für JSF
@Named
@SessionScoped
public class OrderController implements Serializable {
@Inject
private OrderDAO orderDAO;
public String createTestData() { ... }
}
xml
<!-- index.xhtml mit JSF DataTable -->
<h:dataTable value="#{orderController.orders}" var="order">
<h:column>
<f:facet name="header">Order#</f:facet>
#{order.orderNumber}
</h:column>
</h:dataTable>
Das war gestern. Heute geht’s weiter! 🚀
Was dich heute erwartet:
Heute lernst du JSF Professional Features:
Was fehlt noch in deiner Tag 9 App?
❌ Kein Seitenlayout (Header, Footer, Navigation)
❌ Keine Navigation zwischen Pages
❌ Keine Validierung
❌ Keine dynamischen Updates (alles lädt neu)
❌ Keine Error-Handling
Das ändern wir heute!
✅ Templates – Wiederverwendbare Layouts
✅ Navigation – Between Pages ohne URL-Hackerei
✅ Validation – Client + Server
✅ AJAX – Partial Updates ohne Reload
✅ Best Practices – Production-Ready Code
Los geht’s! 🚀
🟢 GRUNDLAGEN: Facelets Templates
Warum Templates?
Problem ohne Templates:
xml
<!-- order-list.xhtml -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html">
<h:head>
<title>Order List</title>
<h:outputStylesheet library="css" name="style.css"/>
</h:head>
<h:body>
<div id="header">
<h1>My Application</h1>
<nav><!-- Navigation --></nav>
</div>
<div id="content">
<!-- Order List Content -->
</div>
<div id="footer">
© 2025 Java Fleet
</div>
</h:body>
</html>
<!-- order-edit.xhtml -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html">
<h:head>
<title>Order Edit</title>
<h:outputStylesheet library="css" name="style.css"/>
</h:head>
<h:body>
<div id="header">
<h1>My Application</h1> <!-- KOPIERT! -->
<nav><!-- Navigation --></nav> <!-- KOPIERT! -->
</div>
<div id="content">
<!-- Order Edit Content -->
</div>
<div id="footer">
© 2025 Java Fleet <!-- KOPIERT! -->
</div>
</h:body>
</html>
Problem: Header, Footer, Navigation auf JEDER Seite kopiert! 😱
Lösung: Templates!
Master-Template erstellen
Datei: /WEB-INF/templates/layout.xhtml
xml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:ui="jakarta.faces.facelets">
<h:head>
<title><ui:insert name="title">Default Title</ui:insert></title>
<h:outputStylesheet library="css" name="style.css"/>
</h:head>
<h:body>
<div id="header">
<h1>☕ Java Fleet Order Management</h1>
<nav>
<h:link outcome="order-list" value="Orders"/>
<h:link outcome="order-edit" value="New Order"/>
</nav>
</div>
<div id="content">
<ui:insert name="content">
Default Content
</ui:insert>
</div>
<div id="footer">
© 2025 Java Fleet Systems Consulting
</div>
</h:body>
</html>
Wichtige Elemente:
<ui:insert name="title">– Platzhalter für Title<ui:insert name="content">– Platzhalter für Content- Default-Werte wenn Page nichts definiert
Page mit Template erstellen
Datei: order-list.xhtml
xml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="jakarta.faces.facelets"
xmlns:h="jakarta.faces.html"
xmlns:f="jakarta.faces.core">
<ui:composition template="/WEB-INF/templates/layout.xhtml">
<ui:define name="title">Order List</ui:define>
<ui:define name="content">
<h2>📋 Orders</h2>
<h:form>
<h:commandButton value="Create Test Data"
action="#{orderController.createTestData}"/>
</h:form>
<h:dataTable value="#{orderController.orders}" var="order"
styleClass="orders-table">
<h:column>
<f:facet name="header">Order#</f:facet>
#{order.orderNumber}
</h:column>
<h:column>
<f:facet name="header">User</f:facet>
#{order.user.username}
</h:column>
<h:column>
<f:facet name="header">Amount</f:facet>
€#{order.totalAmount}
</h:column>
<h:column>
<f:facet name="header">Actions</f:facet>
<h:link outcome="order-edit" value="Edit">
<f:param name="id" value="#{order.id}"/>
</h:link>
</h:column>
</h:dataTable>
</ui:define>
</ui:composition>
</html>
Was passiert:
<ui:composition template="...">– Nutzt Template<ui:define name="title">– Füllt Title-Platzhalter<ui:define name="content">– Füllt Content-Platzhalter- Header, Footer, Navigation kommen automatisch vom Template!
Vorteile von Templates
✅ DRY – Don’t Repeat Yourself
✅ Konsistenz – Alle Pages sehen gleich aus
✅ Wartbarkeit – Navigation ändern = nur Template ändern
✅ Schnellere Entwicklung – Nur Content schreiben
🟡 PROFESSIONALS: Navigation in JSF
Outcome-basierte Navigation
Gestern (Tag 9) hattest du:
java
@Named
@SessionScoped
public class OrderController implements Serializable {
public String createTestData() {
// Create data...
return null; // Bleibt auf selber Seite
}
}
Heute: Navigation zwischen Pages!
java
@Named
@ViewScoped
public class OrderEditBean implements Serializable {
@Inject
private OrderDAO orderDAO;
private Order order;
@PostConstruct
public void init() {
// Get ID from URL parameter
String idParam = FacesContext.getCurrentInstance()
.getExternalContext()
.getRequestParameterMap()
.get("id");
if (idParam != null) {
Long id = Long.parseLong(idParam);
this.order = orderDAO.findById(id);
} else {
this.order = new Order();
}
}
public String save() {
if (order.getId() == null) {
orderDAO.create(order);
} else {
orderDAO.update(order);
}
// Navigate to order-list.xhtml
return "order-list?faces-redirect=true";
}
public String cancel() {
// Navigate without saving
return "order-list?faces-redirect=true";
}
public String delete() {
orderDAO.delete(order.getId());
return "order-list?faces-redirect=true";
}
}
Navigation-Outcomes:
| Return Value | Was passiert? |
|---|---|
null | Bleibt auf selber Page |
"order-list" | Forward zu order-list.xhtml (URL ändert sich NICHT) |
"order-list?faces-redirect=true" | Redirect zu order-list.xhtml (URL ändert sich!) |
Wann Forward vs. Redirect?
- Forward – Innerhalb selber Flow (z.B. Validierungsfehler)
- Redirect – Nach erfolgreicher Aktion (Post-Redirect-Get Pattern!)
Programmatic Navigation
java
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication()
.getNavigationHandler()
.handleNavigation(context, null, "order-list?faces-redirect=true");
🔵 BONUS: Validation in JSF
Problem: Deine Tag 9 App hat keine Validation!
Was passiert wenn User scheiße eingibt?
xml
<!-- Aktuell in deiner Tag 9 App: -->
<h:inputText value="#{orderBean.orderNumber}"/>
<h:inputText value="#{orderBean.amount}"/>
User kann eingeben:
- Leeren Order-Number ❌
- Negativen Amount ❌
- SQL-Injection ❌
Lösung: Validation!
Bean Validation (empfohlen!)
OrderBean mit Validation:
java
@Named
@ViewScoped
public class OrderEditBean implements Serializable {
@Inject
private OrderDAO orderDAO;
private Order order;
// Order Entity mit Validation:
@NotNull(message = "Order number is required")
@Size(min = 5, max = 50, message = "Order number must be 5-50 characters")
@Pattern(regexp = "ORD-[0-9]+", message = "Format: ORD-12345")
private String orderNumber;
@NotNull(message = "Amount is required")
@DecimalMin(value = "0.01", message = "Amount must be positive")
@DecimalMax(value = "999999.99", message = "Amount too large")
private BigDecimal amount;
// Getters/Setters
}
View mit Error Messages:
xml
<h:form>
<h:messages globalOnly="true" styleClass="error-messages"/>
<h:panelGrid columns="3">
<h:outputLabel value="Order#:" for="orderNumber"/>
<h:inputText id="orderNumber"
value="#{orderEditBean.orderNumber}"
required="true"/>
<h:message for="orderNumber" styleClass="error"/>
<h:outputLabel value="Amount:" for="amount"/>
<h:inputText id="amount"
value="#{orderEditBean.amount}"
required="true">
<f:convertNumber type="currency" currencySymbol="€"/>
</h:inputText>
<h:message for="amount" styleClass="error"/>
</h:panelGrid>
<h:commandButton value="Save" action="#{orderEditBean.save}"/>
<h:commandButton value="Cancel" action="#{orderEditBean.cancel}"
immediate="true"/>
</h:form>
Was passiert:
- User gibt Daten ein
- JSF validiert automatisch (Bean Validation Annotations!)
- Bei Fehler:
<h:message>zeigt Fehler an save()wird NUR aufgerufen wenn Validation OK!
Built-in JSF Validators
xml
<!-- Required -->
<h:inputText value="#{bean.name}"
required="true"
requiredMessage="Name is required"/>
<!-- Length -->
<h:inputText value="#{bean.username}">
<f:validateLength minimum="3" maximum="20"/>
</h:inputText>
<!-- Regex -->
<h:inputText value="#{bean.email}">
<f:validateRegex pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"/>
</h:inputText>
<!-- Range -->
<h:inputText value="#{bean.age}">
<f:validateLongRange minimum="18" maximum="99"/>
</h:inputText>
<!-- Double Range -->
<h:inputText value="#{bean.price}">
<f:validateDoubleRange minimum="0.01" maximum="9999.99"/>
</h:inputText>
Empfehlung: Nutze Bean Validation (@NotNull, @Size, etc.) statt JSF Validators! Reason: Funktioniert auch für REST-APIs!
🔵 BONUS: AJAX in JSF
Problem: Deine Tag 9 App lädt immer komplett neu!
Was nervt:
xml
<!-- Aktuell: -->
<h:commandButton value="Create Test Data"
action="#{orderController.createTestData}"/>
Bei Klick:
- Komplette Seite lädt neu ⏳
- Scroll-Position verloren 😡
- Focus verloren 😡
- Slow! 🐌
Lösung: AJAX!
AJAX Partial Page Update
Nur die Table neu laden:
xml
<h:form>
<h:commandButton value="Create Test Data"
action="#{orderController.createTestData}">
<f:ajax execute="@this" render="ordersTable"/>
</h:commandButton>
<h:dataTable id="ordersTable"
value="#{orderController.orders}"
var="order">
<!-- Columns -->
</h:dataTable>
</h:form>
AJAX-Attribute:
execute="@this"– Was soll submitted werden? (nur dieser Button)render="ordersTable"– Was soll neu gerendert werden? (nur die Table)
Magic IDs:
@this– Diese Komponente@form– Das gesamte Formular@all– Die ganze Page (wie ohne AJAX)@none– Nichts
AJAX Search (Live!)
xml
<h:form>
<h:outputLabel value="Search:" for="searchInput"/>
<h:inputText id="searchInput"
value="#{orderController.searchTerm}">
<f:ajax event="keyup"
listener="#{orderController.search}"
render="searchResults"/>
</h:inputText>
<h:panelGroup id="searchResults">
<h:dataTable value="#{orderController.searchResults}"
var="order">
<h:column>#{order.orderNumber}</h:column>
<h:column>#{order.user.username}</h:column>
</h:dataTable>
</h:panelGroup>
</h:form>
Bean:
java
@Named
@ViewScoped
public class OrderController implements Serializable {
@Inject
private OrderDAO orderDAO;
private String searchTerm;
private List<Order> searchResults;
public void search() {
if (searchTerm != null && searchTerm.length() >= 3) {
searchResults = orderDAO.searchByOrderNumber(searchTerm);
} else {
searchResults = new ArrayList<>();
}
}
// Getters/Setters
}
Result: Live-Search während Tippen! ⚡
AJAX Best Practices
✅ Nutze render – Nur nötige Komponenten updaten
✅ Nutze execute – Nur nötige Daten submitten
✅ Nutze listener – Für Logik ohne Navigation
✅ Nutze event – keyup, change, click, blur
❌ Nicht übertreiben – Zu viel AJAX = kompliziert
💬 Real Talk: JSF in 2025 – Lohnt sich das?
Java Fleet Büro, Kaffeemaschine, 16:00 Uhr. Nova scrollt durch ihre fertigen Tag 9 + 10 Projekte.
Nova: „Elyndra, ehrliche Frage: Ich hab jetzt JSF gelernt. Aber alle machen React und Vue.js. Hab ich meine Zeit verschwendet?“
Elyndra: „Gute Frage! Erinner dich an gestern: Wie lange hast du gebraucht für die Order-Liste mit JSF?“
Nova: „Mit JSF? 30 Minuten. Mit React hätte ich…“
Cassian (kommt dazu): „…Stunden gebraucht. Npm install, Webpack Config, State Management, REST API, CORS, Auth…“
Nova: „Ja, aber JSF sieht aus wie 2005…“
Elyndra: „Fair! JSF ist nicht ’sexy‘. Es ist pragmatisch. Lass mich dir die Realität zeigen.“
Cassian: „Ich hab letztens ein Projekt migriert: Vue.js Frontend + Spring REST Backend → JSF + PrimeFaces. Weißt du was? 50% weniger Code. 30% schneller entwickelt. Und der Product Owner war happy, weil keine zwei Deployments mehr.“
Nova: „Warte, PrimeFaces? Was ist das?“
Elyndra: „Ein UI-Component-Library für JSF. Gibt dir fertige Komponenten: DataTable mit Pagination, Autocomplete, File-Upload, Charts – alles out-of-the-box. Und es läuft auf deinem Tomcat von gestern!“
Nova: „Hmm… klingt eigentlich praktisch.“
Cassian: „Ist es auch. Aber hier ist die Wahrheit: Für interne Enterprise-Tools? JSF. Für öffentliche Consumer-Apps? React/Vue.„
Nova: „Also JSF für langweilige Backoffice-Sachen?“
Elyndra: „Genau! Und weißt du was? Die zahlen am besten. Banking, Insurance, Pharma – die brauchen solide, wartbare Enterprise-Apps. Nicht fancy Animationen.“
Cassian: „Plus: JSF-Entwickler sind rar. Wenn du beides kannst – React UND JSF – bist du goldwert für Consulting-Firmen. Ich krieg 850€/Tag für JSF-Projekte.“
Nova: „Wait, 850 pro Tag?!“
Elyndra (lacht): „Ja. React-Entwickler gibt’s wie Sand am Meer. JSF + Jakarta EE Experten? Selten.“
Nova: „Okay, ihr habt mich überzeugt. Also lernen, aber nicht als Hauptfokus?“
Cassian: „Exactly! Es ist ein Tool in deiner Toolbox. Für den richtigen Job.“
Nova: „Alright! Und was kommt nach diesem Kurs?“
Elyndra: „Spring Boot! Ähnliche Konzepte wie CDI, aber größere Community. Oder PrimeFaces für fancy JSF-UIs.“
Nova: „Deal! Aber heute erstmal Tag 10 Challenge fertig machen.“
🎯 Mini-Challenge: Erweitere deine Tag 9 App!
Aufgabe: Mach aus deiner Tag 9 Order-App eine Production-Ready Anwendung!
Requirements:
1. Template erstellen (/WEB-INF/templates/layout.xhtml)
- Header mit Logo + Navigation
- Content-Area (Platzhalter)
- Footer mit Copyright
2. Order-List erweitern (order-list.xhtml)
- Nutze Template
- AJAX-Suche nach Order-Number (keyup-Event)
- Status-Filter Dropdown (AJAX, render Table)
- „New Order“ Button → Navigate zu order-edit
3. Order-Edit Page (order-edit.xhtml)
- Nutze Template
- Form mit Bean Validation:
- Order Number: Required, Pattern ORD-[0-9]+
- Amount: Required, Min 0.01
- User: Required (Dropdown)
<h:messages/>für Fehler- Save Button → Navigate zu order-list
- Cancel Button → Navigate zu order-list (immediate!)
4. Navigation
save()→"order-list?faces-redirect=true"cancel()→"order-list?faces-redirect=true"delete()→ mit JavaScript Confirmation
5. Bonus (optional)
- Delete-Confirmation mit
<p:confirmDialog>(PrimeFaces) - Export zu PDF/Excel
- Pagination auf Order-List
Lösung:
Die Lösung findest du im Download-Bereich am Ende! 🚀
Jakarta Web Aufbau - Tag 10
Tag 10 Quiz
❓ Häufig gestellte Fragen
Frage 1: Tag 9 vs. Tag 10 – Was ist der Unterschied?
Tag 9: JSF-Basics eingeführt
- Erste JSF-Anwendung
- @Named Beans + @Transactional
- Einfaches DataTable
- Fokus: „JSF verstehen“
Tag 10: JSF-Vertiefung
- Templates & Layouts
- Navigation & Routing
- Validation (Built-in + Bean Validation)
- AJAX & Partial Updates
- Fokus: „JSF produktiv nutzen“
Bottom line: Tag 9 = Foundation, Tag 10 = Pro-Features
Frage 2: Warum funktioniert mein @ViewScoped Bean nicht?
Häufigste Fehler:
- Bean ist nicht
Serializable:
java
// FALSCH:
@Named
@ViewScoped
public class UserBean { ... }
// RICHTIG:
@Named
@ViewScoped
public class UserBean implements Serializable { ... }
- Bean hat nicht-serializable Felder:
java
@Named
@ViewScoped
public class UserBean implements Serializable {
@Inject
private UserDAO dao; // OK - CDI-Proxy ist serializable
private HttpServletRequest request; // NICHT OK!
}
Frage 3: Template wird nicht angewendet – was tun?
Checkliste:
xml
<!-- 1. ui:composition statt html-Body? -->
<ui:composition template="/WEB-INF/templates/layout.xhtml">
<!-- Kein <h:body>! -->
</ui:composition>
<!-- 2. Template-Pfad korrekt? -->
template="/WEB-INF/templates/layout.xhtml" <!-- Absolut! -->
<!-- 3. ui:define Name matcht ui:insert? -->
<!-- Template: -->
<ui:insert name="content"/>
<!-- Page: -->
<ui:define name="content"/> <!-- Muss matchen! -->
Frage 4: AJAX funktioniert nicht – Browser Console?
Debug-Steps:
- Browser Console (F12): JavaScript-Fehler?
<h:head>statt<head>?
xml
<!-- FALSCH: -->
<head>
<title>My Page</title>
</head>
<!-- RICHTIG: -->
<h:head>
<title>My Page</title>
</h:head>
- render-Target: ID korrekt?
xml
<h:dataTable id="ordersTable" ...> <!-- ID hier! --> <f:ajax render="ordersTable"/> <!-- Muss matchen! -->
- Component in
<h:form>?
xml
<!-- FALSCH: -->
<h:commandButton ...>
<f:ajax .../>
</h:commandButton>
<!-- RICHTIG: -->
<h:form>
<h:commandButton ...>
<f:ajax .../>
</h:commandButton>
</h:form>
Frage 5: Kann ich JSF auf Tomcat UND Payara deployen?
Ja! Deine Tag 9 Projekte:
- Tag9-JSF-Tomcat: Läuft auf Tomcat 10.x
- Tag9-JSF-Payara: Läuft auf Payara 6.x
Heute (Tag 10) funktioniert auf BEIDEN!
Unterschied:
| Feature | Tomcat | Payara |
|---|---|---|
| CDI | Weld (extern) | Built-in |
| JTA | Atomikos (extern) | Built-in |
| JPA | Hibernate (extern) | EclipseLink (built-in) |
| Deployment | WAR mit Dependencies | WAR klein |
Empfehlung:
- Development: Tomcat (schneller Restart)
- Production: Payara (Full Jakarta EE)
Frage 6: Was ist PrimeFaces und sollte ich es nutzen?
PrimeFaces ist eine UI-Component-Library für JSF.
Was du bekommst:
- 100+ fertige Komponenten
- DataTable mit Pagination, Sorting, Filtering
- Autocomplete, File-Upload, Charts
- Dialog-System, Mobile-Support, Themes
Solltest du PrimeFaces nutzen?
Ja, wenn: ✅ Du schnell schöne UIs brauchst ✅ Du Enterprise-Apps baust ✅ Du DataTables mit Features brauchst
Nein, wenn: ❌ Du maximale Kontrolle über HTML brauchst ❌ Du JSF erst lernen willst (erst Basics!)
Für Tag 10 Challenge: Vanilla JSF reicht! PrimeFaces kommt in separatem Kurs.
🎉 Tag 10 geschafft – Kurs abgeschlossen!
GRATULATION! 🎊
Du hast den Java Web Aufbau Kurs erfolgreich abgeschlossen!
Was du erreicht hast:
- ✅ Filter und Listener gemeistert
- ✅ Security mit Container-Auth & Jakarta Security API implementiert
- ✅ Custom Tags mit SimpleTag & BodyTagSupport erstellt
- ✅ JPA mit komplexen Relationships beherrscht
- ✅ JSF-Grundlagen UND Advanced Features gelernt
- ✅ Production-Ready Enterprise-Apps bauen können
Du kannst jetzt:
- Jakarta EE Web Profile nutzen
- @Named Beans + @Transactional richtig einsetzen
- JSF-Anwendungen mit Templates, Navigation, AJAX entwickeln
- JPA-Relations (@OneToOne, @OneToMany, @ManyToMany) implementieren
- Tomcat UND Payara deployen
Du bist bereit für:
- ✅ Spring Boot (nutzt ähnliche Konzepte!)
- ✅ PrimeFaces (advanced JSF UI)
- ✅ JAX-RS (REST-APIs)
- ✅ Enterprise-Projekte
- ✅ Microservices mit Jakarta EE
Slay! 🔥
🚀 Wie geht’s weiter?
Nächste Kurse:
PrimeFaces Kurs (falls verfügbar)
- UI-Component-Library für JSF
- DataTables, Charts, Dialogs
- Moderne JSF-UIs bauen
JAX-RS REST-APIs
- RESTful Services mit Jakarta EE
- JSON-Handling
- Integration mit JSF-Frontend
Spring Boot
- Ähnliche Konzepte wie CDI
- Microservices
- Cloud-Native Apps
Tipp: Bau ein eigenes Projekt! Das ist die beste Übung!
Learning by doing! 🔧
🔧 Troubleshooting
Problem: Template wird nicht angewendet
Lösung:
- Pfad korrekt?
/WEB-INF/templates/layout.xhtml <ui:composition>statt<h:body>?<ui:define name>matcht<ui:insert name>?
Problem: Navigation funktioniert nicht
Lösung:
- Return-Value korrekt?
"order-list?faces-redirect=true" - .xhtml-File existiert?
- FacesServlet läuft? (web.xml / @FacesConfig)
Problem: AJAX lädt nicht neu
Lösung:
<h:head>statt<head>?render-Target ID korrekt?- Component in
<h:form>? - Browser Console: Fehler?
📚 Downloads
Tag 10 Maven-Projekte:
- Tag10-JSF-Templates-Tomcat.zip – Template-Beispiel für Tomcat
- Tag10-JSF-Templates-Payara.zip – Template-Beispiel für Payara
- Tag10-Challenge-Solution.zip – Musterlösung Challenge
📚 Resources & Links
JSF:
- Jakarta Faces Spec: https://jakarta.ee/specifications/faces/
- Facelets: https://jakarta.ee/specifications/pages/
PrimeFaces:
- Homepage: https://www.primefaces.org/
- Showcase: https://www.primefaces.org/showcase/
Best Practices:
- JSF Best Practices: https://www.baeldung.com/jsf
Du hast es geschafft! 🎊
Bis zum nächsten Kurs! 👋
Elyndra
elyndra.valen@java-developer.online
Senior Developer bei Java Fleet Systems Consulting
Java Web Aufbau – Tag 10 von 10
Teil der Java Fleet Learning-Serie
© 2025 Java Fleet Systems Consulting

