Woche 4 — Review: Spring MVC, REST APIs, Validation und Exception Handling
Ziel
Dieses Review prüft, ob du Woche 4 wirklich verstanden hast.
Themen aus Woche 4:
- Spring MVC Mental Model
DispatcherServletHandlerMappingHandlerAdapter- Controllers
@Controller@RestController@RequestMapping@GetMapping,@PostMapping,@PutMapping,@PatchMapping,@DeleteMapping@PathVariable@RequestParam@RequestHeader@RequestBody@ResponseBodyHttpMessageConverter- Jackson
- DTOs
ResponseEntity- Bean Validation
@Valid@Validated- Nested Validation
- Query Parameter Validation
- Custom Validators
@ExceptionHandler@ControllerAdvice@RestControllerAdvice- Validation Error Handling
- HTTP Error Status Codes
- Clean REST API Design
1. Das große Bild aus Woche 4
Woche 1 hat beantwortet:
Wie erzeugt Spring Objekte und verbindet sie?
Woche 2 hat beantwortet:
Wie konfiguriert, scoped, initialisiert und zerstört Spring diese Beans?
Woche 3 hat beantwortet:
Wie macht Spring Boot Spring einfacher zu konfigurieren, zu starten, zu überwachen und zu debuggen?
Woche 4 beantwortet:
Wie empfängt Spring MVC HTTP Requests, ruft Java Controller Methods auf, validiert Input, gibt JSON zurück und behandelt Fehler?
Merksatz:
Spring MVC wandelt HTTP Requests in Java Method Calls und Java Return Values in HTTP Responses um.
2. Zentraler Spring MVC Request Flow
Ein Request kommt rein:
POST /api/tasks
Content-Type: application/json
{
"title": "Learn Spring MVC"
}
Spring MVC Flow:
1. Client sendet HTTP Request.
2. Embedded Tomcat empfängt ihn.
3. Request geht an DispatcherServlet.
4. DispatcherServlet fragt HandlerMapping nach der passenden Controller Method.
5. HandlerAdapter ruft die Controller Method auf.
6. @RequestBody nutzt HttpMessageConverter, um JSON in ein Java Object zu konvertieren.
7. Controller ruft Service auf.
8. Service gibt DTO zurück.
9. Controller gibt DTO oder ResponseEntity zurück.
10. HttpMessageConverter konvertiert Java Object zu JSON.
11. DispatcherServlet sendet HTTP Response.
Kurzversion zum Merken:
Request -> DispatcherServlet -> HandlerMapping -> HandlerAdapter -> Controller -> Service -> DTO -> JSON Response
3. Zentrale Merksätze
Auswendig lernen:
Spring MVC mappt HTTP Requests auf Java Controller Methods.
DispatcherServlet ist der Front Controller von Spring MVC.
DispatcherServlet koordiniert die Request-Verarbeitung.
HandlerMapping findet die passende Handler Method.
HandlerAdapter ruft die Handler Method auf.
Ein Controller verarbeitet HTTP Requests.
Controllers sollten thin sein.
Services sollten Business Logic enthalten.
@RestController entspricht @Controller plus @ResponseBody.
@Controller kann View Names zurückgeben.
@RestController gibt Response Bodies zurück.
@RequestMapping mappt Requests auf Klassen oder Methods.
@GetMapping mappt GET Requests.
@PostMapping mappt POST Requests.
@PutMapping mappt PUT Requests.
@PatchMapping mappt PATCH Requests.
@DeleteMapping mappt DELETE Requests.
@PathVariable liest Werte aus dem URL Path.
@RequestParam liest Query Parameters.
@RequestHeader liest HTTP Headers.
@RequestBody liest den HTTP Request Body.
@ResponseBody schreibt den Return Value in den HTTP Response Body.
HttpMessageConverter konvertiert zwischen HTTP Bodies und Java Objects.
Jackson konvertiert normalerweise Java Objects zu JSON und JSON zu Java Objects.
DTOs definieren den API Contract.
REST APIs sollten normalerweise DTOs exposen, nicht JPA Entities.
ResponseEntity steuert Status, Headers und Body.
@Valid triggert Bean Validation.
@NotBlank ist normalerweise am besten für required Text.
Nested DTO Validation braucht @Valid auf dem nested Field.
List Element Validation kann List<@Valid ItemDto> nutzen.
Validation prüft die Input-Form.
Business Rules gehören in Service oder Domain Logic.
@ExceptionHandler behandelt Exceptions.
@ControllerAdvice gilt über Controller hinweg.
@RestControllerAdvice entspricht @ControllerAdvice plus @ResponseBody.
MethodArgumentNotValidException tritt häufig bei fehlgeschlagenem @Valid @RequestBody auf.
Invalid JSON liefert normalerweise 400 Bad Request.
Resource not found liefert normalerweise 404 Not Found.
Business Conflict liefert oft 409 Conflict.
401 bedeutet: Authentication fehlt oder ist ungültig.
403 bedeutet: authenticated, aber nicht erlaubt.
4. Concept Map
Spring MVC / REST API
│
├── Request Flow
│ ├── DispatcherServlet
│ ├── HandlerMapping
│ ├── HandlerAdapter
│ ├── Controller
│ └── HttpMessageConverter
│
├── Controllers
│ ├── @Controller
│ ├── @RestController
│ ├── @RequestMapping
│ ├── @GetMapping
│ ├── @PostMapping
│ ├── @PutMapping
│ ├── @PatchMapping
│ └── @DeleteMapping
│
├── Request Data
│ ├── @PathVariable
│ ├── @RequestParam
│ ├── @RequestHeader
│ └── @RequestBody
│
├── Response Data
│ ├── @ResponseBody
│ ├── ResponseEntity
│ ├── DTO
│ ├── status code
│ ├── headers
│ └── body
│
├── JSON
│ ├── Jackson
│ ├── serialization
│ ├── deserialization
│ └── HttpMessageConverter
│
├── Validation
│ ├── spring-boot-starter-validation
│ ├── @Valid
│ ├── @Validated
│ ├── @NotNull
│ ├── @NotBlank
│ ├── @Size
│ ├── nested validation
│ ├── list validation
│ ├── query parameter validation
│ └── custom validators
│
└── Exception Handling
├── @ExceptionHandler
├── @ControllerAdvice
├── @RestControllerAdvice
├── @ResponseStatus
├── ResponseStatusException
├── ProblemDetail
├── MethodArgumentNotValidException
└── structured error response
5. Wichtigste Prüfungsfallen
Falle 1 — DispatcherServlet
Falsch:
DispatcherServlet ist mein Controller.
Richtig:
DispatcherServlet ist der zentrale Front Controller. Er delegiert Requests an die richtige Controller Method.
Falle 2 — HandlerMapping vs. HandlerAdapter
Falsch:
HandlerMapping ruft den Controller auf.
Richtig:
HandlerMapping findet den Handler.
HandlerAdapter ruft den Handler auf.
Merksatz:
Mapping findet.
Adapter ruft auf.
Dispatcher koordiniert.
Falle 3 — @Controller vs. @RestController
Falsch:
@Controller und @RestController sind exakt dasselbe.
Richtig:
@RestController = @Controller + @ResponseBody.
Mit @Controller kann "hello" als View Name gemeint sein.
Mit @RestController bedeutet "hello" Response Body.
Falle 4 — @RequestMapping ohne HTTP Method
Falsch:
@RequestMapping("/api/tasks")
Das kann mehrere HTTP Methods matchen.
Besser:
@GetMapping("/api/tasks")
oder:
@PostMapping("/api/tasks")
Falle 5 — Class-Level und Method-Level Mapping
@RequestMapping("/api/tasks")
@GetMapping("/{id}")
bedeutet:
GET /api/tasks/{id}
Class Path und Method Path werden kombiniert.
Falle 6 — Request Data Annotations
@PathVariable = URL path
@RequestParam = query string
@RequestHeader = HTTP header
@RequestBody = HTTP body
Falle 7 — params vs. @RequestParam
params wählt die Method:
@GetMapping(value = "/api/tasks", params = "status")
@RequestParam liest den Wert:
public List<TaskDto> list(@RequestParam String status)
Merksatz:
params wählt.
@RequestParam liest.
Falle 8 — headers vs. @RequestHeader
headers wählt die Method:
@GetMapping(value = "/api/tasks", headers = "X-API-Version=2")
@RequestHeader liest den Header-Wert:
public List<TaskDto> list(@RequestHeader("X-API-Version") String version)
Falle 9 — consumes vs. produces
consumes = request body format
produces = response body format
consumes prüft:
Content-Type
produces hängt zusammen mit:
Accept
Falle 10 — @RequestBody
Falsch:
@RequestBody liest Query Parameters.
Richtig:
@RequestBody liest den HTTP Request Body.
Falle 11 — ein Request Body
Falsch:
public TaskDto create(
@RequestBody CreateTaskRequest request,
@RequestBody Metadata metadata
)
Richtig:
public TaskDto create(@RequestBody CreateTaskCommand command)
Ein HTTP Request hat einen Body.
Falle 12 — Validation braucht @Valid
Falsch:
public TaskDto create(@RequestBody CreateTaskRequest request)
Richtig:
public TaskDto create(@Valid @RequestBody CreateTaskRequest request)
Validation Annotations brauchen @Valid, um auf Request Body Objects zu laufen.
Falle 13 — @NotNull vs. @NotBlank
Falsch:
@NotNull
String title;
Das erlaubt:
""
" "
Besser für required Text:
@NotBlank
String title;
Falle 14 — Nested Validation
Falsch:
AddressRequest address;
Richtig:
@Valid
AddressRequest address;
Nested DTO Validation braucht @Valid.
Falle 15 — DTO vs. Entity
Falsch:
public UserEntity getUser(...)
Richtig:
public UserDto getUser(...)
REST APIs sollten normalerweise DTOs exposen, nicht JPA Entities.
Falle 16 — Exception Handling
Falsch:
try-catch in jeder Controller Method nutzen.
Richtig:
Sinnvolle Exceptions werfen und global mit @RestControllerAdvice behandeln.
Falle 17 — Error Details
Falsch:
Stack Traces an Clients zurückgeben.
Richtig:
Interne Details loggen. Sichere strukturierte Error Responses zurückgeben.
Übungsfragen
Frage 1
Was ist Spring MVC?
Antwort:
Spring MVC ist das Spring Framework Modul zum Bauen von Web Applications. Es mappt HTTP Requests auf Java Controller Methods und hilft bei Request Data, Response Data, Validation, Exceptions, Views und REST APIs.
Frage 2
Was ist DispatcherServlet?
Antwort:
DispatcherServlet ist der zentrale Front Controller in Spring MVC. Er empfängt eingehende HTTP Requests und koordiniert die Request-Verarbeitung.
Frage 3
Warum heißt DispatcherServlet Front Controller?
Antwort:
Er heißt Front Controller, weil er der zentrale Einstiegspunkt für Spring MVC Requests ist und sie an die richtigen Handler delegiert.
Frage 4
Was macht HandlerMapping?
Antwort:
HandlerMapping findet, welcher Handler — normalerweise eine Controller Method — einen Request verarbeiten soll.
Frage 5
Was macht HandlerAdapter?
Antwort:
HandlerAdapter ruft die von HandlerMapping ausgewählte Handler Method auf.
Frage 6
Was ist der Unterschied zwischen @Controller und @RestController?
Antwort:
@Controller wird oft für traditionelles MVC genutzt und kann View Names zurückgeben. @RestController wird für REST APIs genutzt und schreibt Return Values direkt in den Response Body. @RestController entspricht @Controller plus @ResponseBody.
Frage 7
Was macht @ResponseBody?
Antwort:
@ResponseBody sagt Spring, den Method Return Value direkt in den HTTP Response Body zu schreiben — statt ihn als View Name zu behandeln.
Frage 8
Was macht @RequestMapping?
Antwort:
@RequestMapping mappt HTTP Requests auf Controller Classes oder Methods. Es kann nach Path, HTTP Method, Parameters, Headers, consumes und produces matchen.
Frage 9
Nenne fünf Shortcut Mapping Annotations.
Antwort:
@GetMapping
@PostMapping
@PutMapping
@PatchMapping
@DeleteMapping
Frage 10
Was liest @PathVariable?
Antwort:
@PathVariable liest Werte aus dem URL Path.
Frage 11
Was liest @RequestParam?
Antwort:
@RequestParam liest Query Parameters aus der URL.
Frage 12
Was liest @RequestHeader?
Antwort:
@RequestHeader liest HTTP Request Headers.
Frage 13
Was liest @RequestBody?
Antwort:
@RequestBody liest den HTTP Request Body und konvertiert ihn in ein Java Object.
Frage 14
Was ist HttpMessageConverter?
Antwort:
HttpMessageConverter konvertiert zwischen HTTP Request/Response Bodies und Java Objects.
Frage 15
Wofür wird Jackson genutzt?
Antwort:
Jackson wird normalerweise genutzt, um Java Objects zu JSON zu serialisieren und JSON in Java Objects zu deserialisieren.
Frage 16
Was ist ein DTO?
Antwort:
Ein DTO, oder Data Transfer Object, ist ein Object zum Übertragen von Daten über Layer oder API Boundaries hinweg.
Frage 17
Warum sollten REST APIs normalerweise DTOs statt Entities zurückgeben?
Antwort:
DTOs vermeiden das Exposen interner Database Structure, verhindern Leaks sensibler Fields, reduzieren Lazy Loading und Infinite Recursion Probleme, kontrollieren die Response Shape und trennen den API Contract vom Persistence Model.
Frage 18
Was steuert ResponseEntity?
Antwort:
ResponseEntity steuert HTTP Status Code, Headers und Body.
Frage 19
Wie validierst du einen JSON Request Body?
Antwort:
Validation Annotations auf das Request DTO setzen, spring-boot-starter-validation hinzufügen und @Valid @RequestBody in der Controller Method nutzen.
Frage 20
Was ist der Unterschied zwischen @NotNull, @NotEmpty und @NotBlank?
Antwort:
@NotNull lehnt nur null ab. @NotEmpty lehnt null und leere Werte ab. @NotBlank lehnt null, leere Strings und nur aus Whitespace bestehende Strings ab.
Frage 21
Wie validierst du ein nested DTO?
Antwort:
Validation Annotations auf die nested DTO Fields setzen und @Valid auf das nested Field im Parent DTO setzen.
Frage 22
Was macht @ExceptionHandler?
Antwort:
@ExceptionHandler markiert eine Method, die bestimmte Exception Types behandelt, die von Controller Methods geworfen werden.
Frage 23
Was macht @RestControllerAdvice?
Antwort:
@RestControllerAdvice liefert globales Exception Handling über Controller hinweg und schreibt Return Values direkt in den Response Body. Es entspricht @ControllerAdvice plus @ResponseBody.
Frage 24
Welche Exception tritt häufig auf, wenn @Valid @RequestBody fehlschlägt?
Antwort:
MethodArgumentNotValidException.
Frage 25
Was ist der Unterschied zwischen 401 und 403?
Antwort:
401 Unauthorized bedeutet: Authentication fehlt oder ist ungültig. 403 Forbidden bedeutet: Der User ist authenticated, darf die Aktion aber nicht ausführen.
8. Mini-Mock-Prüfung — Woche 4
Anleitung
Ohne Notizen antworten.
Empfohlene Zeit:
45 Minuten
Bestehensgrenze:
80 %
45 Fragen.
Frage 1
Was ist die Rolle von Spring MVC?
A. HTTP Requests auf Java Controller Methods mappen
B. Java Code kompilieren
C. Nur Database Migrations verwalten
D. Spring Boot ersetzen
Meine Antwort:
Frage 2
Was ist DispatcherServlet?
A. Der zentrale Front Controller von Spring MVC
B. Eine DTO Class
C. Eine Database Entity
D. Eine Validation Annotation
Meine Antwort:
Frage 3
Was macht HandlerMapping?
A. Findet die passende Handler Method
B. Ruft die Controller Method direkt auf
C. Konvertiert JSON zu Java
D. Erzeugt Database Tables
Meine Antwort:
Frage 4
Was macht HandlerAdapter?
A. Ruft die Handler Method auf
B. Findet das Handler Mapping
C. Validiert das Database Schema
D. Erzeugt HTTP Clients
Meine Antwort:
Frage 5
Womit ist @RestController gleichwertig?
A. @Controller + @ResponseBody
B. @Service + @Repository
C. @Entity + @Table
D. @Bean + @Autowired
Meine Antwort:
Frage 6
Mit @Controller bedeutet "home" zurückgeben normalerweise:
A. View Name
B. Immer JSON Response
C. HTTP Header
D. Database Table
Meine Antwort:
Frage 7
Mit @RestController bedeutet "hello" zurückgeben:
A. Response Body Text
B. View Name
C. Bean Name
D. Profile Name
Meine Antwort:
Frage 8
Was mappt @GetMapping?
A. GET Requests
B. POST Requests
C. Nur DELETE Requests
D. Startup Events
Meine Antwort:
Frage 9
Was repräsentiert @PostMapping in REST häufig?
A. Resource erstellen oder Command ausführen
B. Nur Resource lesen
C. Nur Resource löschen
D. Nur Template rendern
Meine Antwort:
Frage 10
Was ergibt class-level @RequestMapping("/api/tasks") plus method-level @GetMapping("/{id}")?
A. GET /api/tasks/{id}
B. POST /api/tasks/{id}
C. Nur GET /{id}
D. Nur /api/tasks
Meine Antwort:
Frage 11
Was liest @PathVariable?
A. URL Path Value
B. Query Parameter
C. Request Header
D. Request Body
Meine Antwort:
Frage 12
Was liest @RequestParam?
A. Query Parameter
B. Request Body
C. Response Body
D. Bean Name
Meine Antwort:
Frage 13
Was liest @RequestHeader?
A. HTTP Header
B. Path Value
C. JSON Body
D. Database Row
Meine Antwort:
Frage 14
Was liest @RequestBody?
A. HTTP Request Body
B. Query Parameter
C. URL Path
D. Actuator Endpoint
Meine Antwort:
Frage 15
Was macht @ResponseBody?
A. Schreibt Return Value in den HTTP Response Body
B. Liest Query Parameters
C. Erzeugt eine Database Transaction
D. Startet Tomcat
Meine Antwort:
Frage 16
Was ist der Unterschied zwischen params und @RequestParam?
A. params wählt Method; @RequestParam liest Wert
B. Sie sind exakt dasselbe
C. params liest JSON Body
D. @RequestParam steuert Headers
Meine Antwort:
Frage 17
Was ist der Unterschied zwischen headers und @RequestHeader?
A. headers wählt Method; @RequestHeader liest Wert
B. Sie sind exakt dasselbe
C. headers liest Request Body
D. @RequestHeader erzeugt Beans
Meine Antwort:
Frage 18
Was bedeutet consumes = "application/json"?
A. Endpoint akzeptiert JSON Request Body
B. Endpoint liefert nur HTML
C. Endpoint braucht Query Param
D. Endpoint deaktiviert Validation
Meine Antwort:
Frage 19
Was bedeutet produces = "application/json"?
A. Endpoint kann JSON Response liefern
B. Endpoint konsumiert Plain Text
C. Endpoint braucht Path Variable
D. Endpoint erzeugt JSON File auf Disk
Meine Antwort:
Frage 20
Welcher Header beschreibt das Request Body Format?
A. Content-Type
B. Accept
C. Nur Authorization
D. Location
Meine Antwort:
Frage 21
Welcher Header beschreibt das Response Format, das der Client will?
A. Accept
B. Content-Type
C. Nur Host
D. Nur Cookie
Meine Antwort:
Frage 22
Was kann 415 Unsupported Media Type verursachen?
A. Falscher Request Content-Type für die consumes Condition des Endpoints
B. Fehlende Database Row
C. Nur falsches Passwort
D. Fehlender Java Compiler
Meine Antwort:
Frage 23
Was kann ambiguous Mapping verursachen?
A. Zwei Methods matchen denselben Request
B. Keine DTOs vorhanden
C. Zu viele Services
D. Fehlender Actuator
Meine Antwort:
Frage 24
Was konvertiert JSON zu Java und Java zu JSON?
A. HttpMessageConverter, normalerweise mit Jackson
B. Nur HandlerMapping
C. @Service
D. @Repository
Meine Antwort:
Frage 25
Was ist Jackson?
A. JSON Serialization/Deserialization Library
B. Database Server
C. Web Browser
D. Build Tool
Meine Antwort:
Frage 26
Was ist Serialization?
A. Java Object zu JSON
B. JSON zu Java Object
C. Nur SQL zu Java
D. HTML zu CSS
Meine Antwort:
Frage 27
Was ist Deserialization?
A. JSON zu Java Object
B. Java Object zu JSON
C. Nur Java zu Bytecode
D. Nur Entity zu Table
Meine Antwort:
Frage 28
Was ist ein DTO?
A. Data Transfer Object
B. Database Transaction Object
C. Docker Test Object
D. Default Type Object
Meine Antwort:
Frage 29
Warum sollten REST APIs normalerweise DTOs statt Entities zurückgeben?
A. Um internes Model und sensible Fields nicht zu leaken
B. Weil Entities nicht kompilieren
C. Weil DTOs immer Database Tables erzeugen
D. Weil Controller technisch keine Entities zurückgeben können
Meine Antwort:
Frage 30
Was steuert ResponseEntity?
A. Status, Headers und Body
B. Nur Database Connection
C. Nur Validation Annotations
D. Nur Package Scanning
Meine Antwort:
Frage 31
Wie gibst du 204 No Content zurück?
A. ResponseEntity.noContent().build()
B. ResponseEntity.ok(body)
C. Immer return null
D. @RequestBody
Meine Antwort:
Frage 32
Welche Dependency brauchst du häufig für Bean Validation?
A. spring-boot-starter-validation
B. spring-boot-starter-css
C. spring-boot-starter-html
D. spring-boot-starter-browser
Meine Antwort:
Frage 33
Was triggert Request Body Validation?
A. @Valid @RequestBody
B. Nur @RequestBody
C. Nur @GetMapping
D. Nur @PathVariable
Meine Antwort:
Frage 34
Welche Annotation ist am besten für required Text Fields?
A. @NotBlank
B. Nur @NotNull
C. @Autowired
D. @Bean
Meine Antwort:
Frage 35
Lehnt @Size null von sich aus ab?
A. Nein
B. Ja, immer
C. Nur in Controllers
D. Nur in Entities
Meine Antwort:
Frage 36
Wie validierst du nested DTOs?
A. @Valid auf das nested Field setzen
B. @GetMapping nutzen
C. @Bean nutzen
D. Nur @PathVariable nutzen
Meine Antwort:
Frage 37
Wie validierst du jedes Object in einer List?
A. List<@Valid ItemRequest>
B. @RequestHeader List<ItemRequest>
C. @Bean List<ItemRequest>
D. @Controller List<ItemRequest>
Meine Antwort:
Frage 38
Was passiert häufig, wenn @Valid @RequestBody fehlschlägt?
A. MethodArgumentNotValidException
B. Immer NullPointerException
C. ApplicationReadyEvent
D. BeanFactory Restart
Meine Antwort:
Frage 39
Was ist @ExceptionHandler?
A. Method Annotation zum Behandeln von Exceptions
B. DTO Annotation
C. Database Annotation
D. Query Parameter Annotation
Meine Antwort:
Frage 40
Was ist @RestControllerAdvice?
A. Globales REST Exception Handling Advice
B. Ein JPA Repository
C. Eine JSON Field Annotation
D. Nur ein Package Scanner
Meine Antwort:
Frage 41
Welchen Status sollte eine fehlende Resource normalerweise liefern?
A. 404 Not Found
B. 201 Created
C. 204 No Content
D. 415 Unsupported Media Type
Meine Antwort:
Frage 42
Welchen Status sollten Validation Errors normalerweise liefern?
A. 400 Bad Request
B. 200 OK
C. 201 Created
D. Immer 500
Meine Antwort:
Frage 43
Welcher Status wird oft für Business Conflict genutzt?
A. 409 Conflict
B. 204 No Content
C. 302 Found
D. 100 Continue
Meine Antwort:
Frage 44
Was bedeutet 401 Unauthorized?
A. Authentication fehlt oder ist ungültig
B. Authenticated, aber nicht erlaubt
C. Resource not found
D. Nur invalid JSON
Meine Antwort:
Frage 45
Was bedeutet 403 Forbidden?
A. Authenticated, aber nicht erlaubt
B. Authentication fehlt
C. Request Body ist invalid JSON
D. Endpoint konsumiert JSON
Meine Antwort:
9. Lösungen Mini-Mock-Prüfung
Lösungsschlüssel
1. A
2. A
3. A
4. A
5. A
6. A
7. A
8. A
9. A
10. A
11. A
12. A
13. A
14. A
15. A
16. A
17. A
18. A
19. A
20. A
21. A
22. A
23. A
24. A
25. A
26. A
27. A
28. A
29. A
30. A
31. A
32. A
33. A
34. A
35. A
36. A
37. A
38. A
39. A
40. A
41. A
42. A
43. A
44. A
45. A
10. Punkte
Gesamtfragen: 45
Richtige Antworten:
Falsche Antworten:
Punkte:
Punkteberechnung:
richtige Antworten / 45 * 100
Beispiel:
36 / 45 * 100 = 80 %
11. Fehler-Review-Vorlage
Für jede falsche Antwort schreibst du:
## Fehler
Fragennummer:
Meine falsche Antwort:
Richtige Antwort:
Warum ich falsch lag:
Richtiges Konzept:
Merksatz:
Beispiel:
## Fehler
Fragennummer: 16
Meine falsche Antwort: B
Richtige Antwort: A
Warum ich falsch lag:
Ich dachte, params und @RequestParam sind dasselbe.
Richtiges Konzept:
params ist eine Mapping Condition. @RequestParam liest den Wert.
Merksatz:
params wählt. @RequestParam liest.
12. Szenario-Fragen aus der Praxis
Szenario 1 — @Controller gibt View Name zurück
Code:
@Controller
@RequestMapping("/api/hello")
public class HelloController {
@GetMapping
public String hello() {
return "hello";
}
}
Erwarteter Response Body:
hello
Aber Spring sucht eine View namens hello.
Frage:
Was ist falsch?
Meine Antwort:
Musterantwort
Die Class nutzt @Controller, daher kann ein zurückgegebener String als View Name behandelt werden. Für REST APIs nutze @RestController oder füge @ResponseBody hinzu.
Richtig:
@RestController
@RequestMapping("/api/hello")
public class HelloController {
@GetMapping
public String hello() {
return "hello";
}
}
Szenario 2 — fehlendes @RequestBody
Code:
@PostMapping("/api/tasks")
public TaskDto create(CreateTaskRequest request) {
return taskService.create(request);
}
Request:
POST /api/tasks
Content-Type: application/json
{
"title": "Learn Spring"
}
Frage:
Warum bindet JSON möglicherweise nicht korrekt?
Meine Antwort:
Musterantwort
Dem Controller Parameter fehlt @RequestBody. Für JSON Request Bodies nutze:
@PostMapping("/api/tasks")
public TaskDto create(@RequestBody CreateTaskRequest request) {
return taskService.create(request);
}
Szenario 3 — Validation läuft nicht
DTO:
public record CreateTaskRequest(
@NotBlank String title
) {
}
Controller:
@PostMapping("/api/tasks")
public TaskDto create(@RequestBody CreateTaskRequest request) {
return taskService.create(request);
}
Request:
{
"title": ""
}
Validation läuft nicht.
Frage:
Was fehlt?
Meine Antwort:
Musterantwort
@Valid fehlt.
Richtig:
@PostMapping("/api/tasks")
public TaskDto create(@Valid @RequestBody CreateTaskRequest request) {
return taskService.create(request);
}
Szenario 4 — Nested Validation läuft nicht
DTO:
public record CreateClientRequest(
@NotBlank String name,
AddressRequest address
) {
}
public record AddressRequest(
@NotBlank String street,
@NotBlank String city
) {
}
Frage:
Warum werden street und city nicht validiert?
Meine Antwort:
Musterantwort
Dem nested Field address fehlt @Valid.
Richtig:
public record CreateClientRequest(
@NotBlank String name,
@Valid AddressRequest address
) {
}
Wenn address required ist:
public record CreateClientRequest(
@NotBlank String name,
@Valid @NotNull AddressRequest address
) {
}
Szenario 5 — falscher Content-Type
Controller:
@PostMapping(
value = "/api/tasks",
consumes = MediaType.APPLICATION_JSON_VALUE
)
public TaskDto create(@RequestBody CreateTaskRequest request) {
return taskService.create(request);
}
Request:
POST /api/tasks
Content-Type: text/plain
hello
Frage:
Welcher Status ist wahrscheinlich?
Meine Antwort:
Musterantwort
415 Unsupported Media Type, weil der Endpoint JSON konsumiert, der Request aber text/plain sendet.
Szenario 6 — ambiguous Mapping
Code:
@GetMapping("/api/tasks")
public List<TaskDto> list1() {
return taskService.findAll();
}
@GetMapping("/api/tasks")
public List<TaskDto> list2() {
return taskService.findRecent();
}
Frage:
Was ist falsch?
Meine Antwort:
Musterantwort
Beide Methods matchen denselben Request: GET /api/tasks. Spring kann nicht entscheiden, welche Method genutzt werden soll, und kann mit einem ambiguous Mapping Error fehlschlagen.
Szenario 7 — Entity direkt zurückgeben
Code:
@GetMapping("/api/users/{id}")
public UserEntity getUser(@PathVariable Long id) {
return userRepository.findById(id).orElseThrow();
}
Frage:
Warum ist das riskant?
Meine Antwort:
Musterantwort
Eine Entity zurückzugeben kann interne Fields, sensible Daten, lazy Relationships, Infinite Recursion und Database Structure exposen. Gib stattdessen ein DTO zurück.
Szenario 8 — rohe Exception exposed
Code:
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handle(Exception ex) {
return ResponseEntity.internalServerError().body(ex.toString());
}
Frage:
Was ist falsch?
Meine Antwort:
Musterantwort
Es exposed rohe interne Exception Details an den Client. Das kann Class Names, SQL Details, File Paths, Package Names oder sensible Informationen leaken. Logge die Exception intern und gib eine sichere strukturierte Error Response zurück.
13. Mündliche Abschlussprüfung — Woche 4
Laut beantworten.
Frage 1
Erkläre den Spring MVC Request Flow.
Frage 2
Erkläre DispatcherServlet.
Frage 3
Erkläre HandlerMapping und HandlerAdapter.
Frage 4
Erkläre @Controller vs. @RestController.
Frage 5
Erkläre @RequestMapping und Shortcut Mappings.
Frage 6
Erkläre @PathVariable, @RequestParam, @RequestHeader und @RequestBody.
Frage 7
Erkläre consumes und produces.
Frage 8
Erkläre HttpMessageConverter und Jackson.
Frage 9
Erkläre DTOs und warum APIs Entities nicht direkt exposen sollten.
Frage 10
Erkläre ResponseEntity.
Frage 11
Erkläre Request Body Validation.
Frage 12
Erkläre Nested Validation.
Frage 13
Erkläre Query Parameter Validation.
Frage 14
Erkläre globales Exception Handling.
Frage 15
Erkläre Validation Error Handling.
14. Gute mündliche Antworten
Mündliche Antwort 1 — Spring MVC Request Flow
Wenn ein HTTP Request reinkommt, empfängt der embedded Servlet Container ihn und leitet ihn an Spring MVCs DispatcherServlet weiter. Der DispatcherServlet fragt HandlerMapping, welche Controller Method passt. Dann ruft HandlerAdapter diese Method auf. Der Controller ruft normalerweise einen Service auf und gibt ein DTO oder ResponseEntity zurück. Für REST APIs konvertiert ein HttpMessageConverter — normalerweise mit Jackson — Java Objects in JSON Responses.
Mündliche Antwort 2 — DispatcherServlet
DispatcherServlet ist der Front Controller von Spring MVC. Er ist der zentrale Einstiegspunkt für HTTP Requests. Er koordiniert den Request Flow, indem er den richtigen Handler findet, ihn über einen Adapter aufruft, das Ergebnis verarbeitet, mit Message Converters arbeitet und die HTTP Response zurückgibt.
Mündliche Antwort 3 — HandlerMapping und HandlerAdapter
HandlerMapping findet, welche Controller Method den Request verarbeiten soll. HandlerAdapter ruft diese Controller Method auf. Kurz: Mapping findet, Adapter ruft auf.
Mündliche Antwort 4 — @Controller vs. @RestController
@Controller markiert eine Class als Spring MVC Controller, oft für server-rendered Views. Ein zurückgegebener String kann als View Name behandelt werden. @RestController wird für REST APIs genutzt. Es enthält @ResponseBody, daher werden Return Values direkt in den HTTP Response Body geschrieben — normalerweise als JSON.
Mündliche Antwort 5 — Request Mapping
@RequestMapping mappt HTTP Requests auf Controller Classes oder Methods. Es kann nach Path, Method, params, headers, consumes und produces matchen. In REST APIs nutzt du normalerweise Shortcut Annotations wie @GetMapping, @PostMapping, @PutMapping, @PatchMapping und @DeleteMapping.
Mündliche Antwort 6 — Request Data Annotations
@PathVariable liest Werte aus dem URL Path, z. B. /tasks/{id}. @RequestParam liest Query Parameters, z. B. /tasks?page=0. @RequestHeader liest HTTP Headers. @RequestBody liest den HTTP Request Body und konvertiert ihn in ein Java Object.
Mündliche Antwort 7 — consumes und produces
consumes beschreibt, welchen Request Body Media Type der Endpoint akzeptiert — basierend auf dem Content-Type Header. produces beschreibt, welchen Response Media Type der Endpoint liefern kann — basierend auf Content Negotiation und dem Accept Header.
Mündliche Antwort 8 — HttpMessageConverter und Jackson
HttpMessageConverter konvertiert zwischen HTTP Bodies und Java Objects. Für JSON in Spring Boot MVC Applications wird normalerweise Jackson genutzt. Es deserialisiert JSON Request Bodies in Java DTOs und serialisiert Java DTOs in JSON Response Bodies.
Mündliche Antwort 9 — DTOs
Ein DTO ist ein Data Transfer Object zum Definieren des API Contracts. Request DTOs beschreiben, was Clients senden; Response DTOs beschreiben, was der Server zurückgibt. APIs sollten normalerweise DTOs statt JPA Entities zurückgeben, um interne Database Structure, sensible Fields, Lazy Loading Probleme und Infinite Recursion zu vermeiden.
Mündliche Antwort 10 — ResponseEntity
ResponseEntity repräsentiert die vollständige HTTP Response. Es erlaubt dir, Status Code, Headers und Body zu steuern. Du kannst z. B. nach dem Erstellen einer Resource 201 Created mit einem Location Header zurückgeben oder nach dem Löschen 204 No Content.
Mündliche Antwort 11 — Request Body Validation
Um einen Request Body zu validieren, setzt du Validation Annotations auf das Request DTO, z. B. @NotBlank, @Size oder @Email. Dann nutzt du @Valid @RequestBody in der Controller Method. Wenn Validation fehlschlägt, wirft Spring häufig MethodArgumentNotValidException und liefert 400 Bad Request.
Mündliche Antwort 12 — Nested Validation
Für nested DTO Validation setzt du Validation Annotations auf die nested DTO Fields und fügst @Valid auf das nested Field im Parent DTO hinzu. Wenn das nested Object required ist, fügst du auch @NotNull hinzu.
Mündliche Antwort 13 — Query Parameter Validation
Um Query Parameters zu validieren, setzt du Constraints direkt auf Method Parameters, z. B. @RequestParam @Min(0) int page und @RequestParam @Max(100) int size. In vielen Projekten wird @Validated auf der Controller Class genutzt; in modernem Spring MVC kann Method Validation auch über built-in Support laufen.
Mündliche Antwort 14 — Globales Exception Handling
Für REST APIs nutzt du normalerweise @RestControllerAdvice mit @ExceptionHandler Methods. So mapst du Custom Exceptions auf HTTP Status Codes und strukturierte Error Responses. Z. B. ResourceNotFoundException auf 404, Validation Errors auf 400 und Business Conflicts auf 409.
Mündliche Antwort 15 — Validation Error Handling
Wenn @Valid @RequestBody fehlschlägt, wirft Spring häufig MethodArgumentNotValidException. Du behandelst das global in @RestControllerAdvice, extrahierst Field Errors aus dem Binding Result und gibst eine strukturierte 400 Bad Request Response mit Field Names und Messages zurück.
15. Readiness-Checkliste Woche 4
Bevor du zu Woche 5 weitergehst, solltest du alles Folgende abhaken können:
[ ] Ich kann Spring MVC erklären.
[ ] Ich kann DispatcherServlet erklären.
[ ] Ich weiß, warum DispatcherServlet der Front Controller ist.
[ ] Ich kann HandlerMapping erklären.
[ ] Ich kann HandlerAdapter erklären.
[ ] Ich kann den vollständigen Request Flow erklären.
[ ] Ich kann @Controller erklären.
[ ] Ich kann @RestController erklären.
[ ] Ich weiß: @RestController = @Controller + @ResponseBody.
[ ] Ich kann @RequestMapping erklären.
[ ] Ich kenne @GetMapping, @PostMapping, @PutMapping, @PatchMapping, @DeleteMapping.
[ ] Ich kann class-level plus method-level Mappings erklären.
[ ] Ich kann @PathVariable erklären.
[ ] Ich kann @RequestParam erklären.
[ ] Ich kann @RequestHeader erklären.
[ ] Ich kann @RequestBody erklären.
[ ] Ich kann @ResponseBody erklären.
[ ] Ich kann params vs. @RequestParam erklären.
[ ] Ich kann headers vs. @RequestHeader erklären.
[ ] Ich kann consumes erklären.
[ ] Ich kann produces erklären.
[ ] Ich kenne Content-Type vs. Accept.
[ ] Ich kenne gängige Mapping Errors: 404, 405, 415, 406, 400.
[ ] Ich kann HttpMessageConverter erklären.
[ ] Ich kann Jackson erklären.
[ ] Ich kenne Serialization und Deserialization.
[ ] Ich kann DTOs erklären.
[ ] Ich weiß, warum DTOs besser sind als Entities zu exposen.
[ ] Ich kann ResponseEntity erklären.
[ ] Ich kann 200, 201, 204 und 404 zurückgeben.
[ ] Ich kann Bean Validation erklären.
[ ] Ich kenne spring-boot-starter-validation.
[ ] Ich kann @Valid erklären.
[ ] Ich kann @Validated erklären.
[ ] Ich kenne @NotNull vs. @NotEmpty vs. @NotBlank.
[ ] Ich weiß, dass @Size null von sich aus nicht ablehnt.
[ ] Ich kann Request Bodies validieren.
[ ] Ich kann nested DTOs validieren.
[ ] Ich kann Lists validieren.
[ ] Ich kann Query Parameters validieren.
[ ] Ich kann Custom Validators erklären.
[ ] Ich kann Validation vs. Business Rules erklären.
[ ] Ich kann @ExceptionHandler erklären.
[ ] Ich kann @ControllerAdvice erklären.
[ ] Ich kann @RestControllerAdvice erklären.
[ ] Ich kann Validation Errors global behandeln.
[ ] Ich kenne gängige Error Statuses: 400, 401, 403, 404, 409, 415, 500.
[ ] Ich weiß, dass Stack Traces nicht an Clients exposed werden sollten.
16. Schwache Themen vor Woche 5
Schwache Themen hier eintragen:
## Meine Schwachstellen
1.
2.
3.
4.
5.
Für jedes schwache Thema:
## Schwachstelle
Thema:
Warum es verwirrend ist:
Richtige Erklärung:
Code-Beispiel:
Merksatz:
17. Abschluss-Zusammenfassung Woche 4
Woche 4 hat dir gezeigt, wie du REST APIs mit Spring MVC baust.
Die wichtigste Idee:
Spring MVC empfängt HTTP Requests, ruft Controller Methods auf, validiert Input, konvertiert JSON und gibt HTTP Responses zurück.
Der Request Flow ist:
Request -> DispatcherServlet -> HandlerMapping -> HandlerAdapter -> Controller -> Service -> Response
Für REST APIs:
@RestController gibt Response Bodies zurück.
@RequestBody liest JSON in DTOs.
HttpMessageConverter und Jackson konvertieren JSON und Java Objects.
ResponseEntity steuert Status, Headers und Body.
DTOs schützen die API Boundary.
@Valid triggert Validation.
@RestControllerAdvice behandelt Errors global.
Wenn du Woche 4 gut verstanden hast, bist du bereit für Woche 5:
Spring Data, Transactions und Persistence