Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla
Keskitetään kaikkien ohjainten poikkeusten käsittely @ExceptionHandler- ja @ControllerAdvice-annotaatioilla.
Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Keskitetyn käsittelyn puuttumisen ongelma
Ilman keskitettyä poikkeustenkäsittelyä jokainen controller-metodi tarvitsee try-catch-lohkoja, virhevastausten muodostaminen toistuu ja poikkeusten yksityiskohtia voi vuotaa asiakkaille.
@ControllerAdvice ja @RestControllerAdvice
@ControllerAdvice määrittää keskitetyn poikkeustenkäsittelijäluokan. @RestControllerAdvice lisää @ResponseBody-annotaation, joten kaikki käsittelijämetodit palauttavat JSON-muotoisen vastauksen automaattisesti.
@RestControllerAdvice
public class GlobalExceptionHandler {
// @ExceptionHandler methods go here
}@ExceptionHandler-metodit
Merkitkää metodi annotaatiolla @ExceptionHandler(ExceptionType.class). Spring ohjaa kyseisen tyypin poikkeukset ja sen aliluokkien poikkeukset tähän metodiin. Palauttakaa ResponseEntity, joka sisältää tilanteeseen sopivan statuskoodin.
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("NOT_FOUND", ex.getMessage()));
}Useiden poikkeustyyppien käsittely
Luetelkaa useita poikkeustyyppejä yhdessä käsittelijässä tai käyttäkää yhteistä yliluokkaa. Spring valitsee käytettävissä olevista käsittelijöistä tarkimmin sopivan.
@ExceptionHandler({IllegalArgumentException.class, IllegalStateException.class})
public ResponseEntity<ErrorResponse> handleBadRequest(RuntimeException ex) {
return ResponseEntity.badRequest()
.body(new ErrorResponse("BAD_REQUEST", ex.getMessage()));
}Validointivirheiden käsittely
Ottakaa MethodArgumentNotValidException kiinni, jotta voitte poimia @Valid-annotaatiolla validoitujen pyyntörunkojen kenttätason virheet.
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>> handleValidation(MethodArgumentNotValidException ex) {
Map<String, String> fieldErrors = new LinkedHashMap<>();
ex.getBindingResult().getFieldErrors().forEach(e ->
fieldErrors.put(e.getField(), e.getDefaultMessage()));
return ResponseEntity.badRequest()
.body(Map.of("errors", fieldErrors, "status", 400));
}Rajoiterikkomusten käsittely
ConstraintViolationException heitetään, kun palvelutasolla validoidaan metodiparametreja @Validated-annotaation avulla. Käsitelkää se erikseen MVC-validoinnin virheistä.
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Map<String, String>> handleConstraint(ConstraintViolationException ex) {
Map<String, String> errors = new LinkedHashMap<>();
ex.getConstraintViolations().forEach(v ->
errors.put(v.getPropertyPath().toString(), v.getMessage()));
return ResponseEntity.badRequest().body(errors);
}HttpServletRequest-olion käyttäminen
Lisätkää parametriksi HttpServletRequest, jotta voitte saada pyynnön tiedot (URL-osoitteen, metodin ja otsakkeet) lokitusta tai virhevastausta varten.
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAll(Exception ex, HttpServletRequest req) {
log.error("Unhandled error on {} {}", req.getMethod(), req.getRequestURI(), ex);
return ResponseEntity.internalServerError()
.body(new ErrorResponse("INTERNAL_ERROR", "Unexpected error"));
}@ResponseStatus poikkeusluokissa
Merkitkää mukautetut poikkeusluokat @ResponseStatus-annotaatiolla, jolloin HTTP-status asetetaan automaattisesti ilman käsittelijämetodia. Tämä on yksinkertaisempi ratkaisu suoraviivaisissa tapauksissa.
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String msg) { super(msg); }
}@ControllerAdvicen rajaus
Rajaatte neuvonnan tiettyihin paketteihin, annotaatioihin tai yliluokkiin käyttämällä @ControllerAdvice-annotaation attribuutteja.
@RestControllerAdvice(basePackages = "com.example.api")
public class ApiExceptionHandler { ... }
@RestControllerAdvice(assignableTypes = {UserController.class, OrderController.class})
public class SpecificHandler { ... }Poikkeuskäsittelijöiden lokitus
Kirjatkaa poikkeukset asianmukaisella lokitasolla: käyttäjän aiheuttamat virheet (4xx) tasolla WARN ja odottamattomat virheet (5xx) tasolla ERROR koko pinotiedon kanssa.
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAll(Exception ex, HttpServletRequest req) {
if (ex instanceof BusinessException) log.warn("Business error: {}", ex.getMessage());
else log.error("Unexpected error on {}", req.getRequestURI(), ex);
return ...
}Poikkeuskäsittelijöiden prioriteetti
Spring valitsee täsmällisimmän käsittelijän. Jos ResourceNotFoundException extends RuntimeException, ResourceNotFoundException-käsittelijä saa etusijan RuntimeException-käsittelijään nähden.
Pikatarkistus
Millä annotaatiolla metodi merkitään käsittelemään tiettyä poikkeustyyppiä kaikkialla sovelluksessa?
Kertaus
Keskittäkää virheenkäsittely käyttämällä yhdistelmää @RestControllerAdvice + @ExceptionHandler. Palauttakaa ResponseEntity, jonka virherakenne on yhdenmukainen. Käsitelkää validointi (MethodArgumentNotValidException) ja rajoitteet (ConstraintViolationException) erikseen. Kirjatkaa 4xx-virheet tasolla WARN ja 5xx-virheet tasolla ERROR.
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla” ilmainen?
Kyllä – oppitunnin ”Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla”?
Keskitetään kaikkien ohjainten poikkeusten käsittely @ExceptionHandler- ja @ControllerAdvice-annotaatioilla. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Bean Validation: @NotNull, @Size, @Pattern
- Mukautetut rajoiteannotaatiot
- Poikkeusten keskitetty käsittely @ControllerAdvice-annotaatiolla
- RFC 7807:n ongelmatiedot ja yhdenmukaiset virhevastaustaukset