Java Academy · leksjon

Global unntakshåndtering med @ControllerAdvice

Sentraliser unntakshåndteringen på tvers av alle kontrollere med @ExceptionHandler og @ControllerAdvice.

Leksjon 3 av 413 trinn

Global unntakshåndtering med @ControllerAdvice er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.

Problemet uten global håndtering

Uten global unntakshåndtering trenger hver controllermetode try-catch-blokker, bygging av feilresponser blir duplisert, og unntaksdetaljer kan lekke til klientene.

@ControllerAdvice og @RestControllerAdvice

@ControllerAdvice definerer en global klasse for unntakshåndtering. @RestControllerAdvice legger til @ResponseBody, slik at alle håndteringsmetoder automatisk returnerer JSON.

@RestControllerAdvice
public class GlobalExceptionHandler {
    // @ExceptionHandler methods go here
}

@ExceptionHandler-metoder

Annoter en metode med @ExceptionHandler(ExceptionType.class). Spring ruter unntak av denne typen (og underklasser) til metoden. Returner en ResponseEntity med riktig status.

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
    return ResponseEntity.status(HttpStatus.NOT_FOUND)
        .body(new ErrorResponse("NOT_FOUND", ex.getMessage()));
}

Håndtere flere unntakstyper

List opp flere unntakstyper i én håndterer, eller bruk en felles basisklasse. Spring velger den mest spesifikke tilgjengelige håndtereren.

@ExceptionHandler({IllegalArgumentException.class, IllegalStateException.class})
public ResponseEntity<ErrorResponse> handleBadRequest(RuntimeException ex) {
    return ResponseEntity.badRequest()
        .body(new ErrorResponse("BAD_REQUEST", ex.getMessage()));
}

Håndtere valideringsfeil

Fang opp MethodArgumentNotValidException for å hente ut feltfeil fra request-body-er som er validert med @Valid.

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

Håndtere constraint-brudd

ConstraintViolationException kastes når metodeparametere valideres med @Validated på servicelaget. Håndter dette separat fra MVC-valideringsfeil.

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

Tilgang til HttpServletRequest

Legg til HttpServletRequest som en parameter for å hente forespørselsdetaljer (URL, metode og headere) til logging eller inkludering i feilresponsen.

@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 på unntaksklasser

Annoter egendefinerte unntaksklasser med @ResponseStatus for automatisk å angi HTTP-statusen uten en håndteringsmetode — enklere i ukompliserte tilfeller.

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String msg) { super(msg); }
}

Avgrense @ControllerAdvice

Begrens advice-en til bestemte pakker, annotasjoner eller basisklasser ved hjelp av attributter på @ControllerAdvice.

@RestControllerAdvice(basePackages = "com.example.api")
public class ApiExceptionHandler { ... }
@RestControllerAdvice(assignableTypes = {UserController.class, OrderController.class})
public class SpecificHandler { ... }

Logging i unntakshåndterere

Logg unntak på riktig nivå: brukerfeil (4xx) på WARN, uventede feil (5xx) på ERROR med hele stacktracen.

@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 ...
}

Prioritet for exception-håndterere

Spring velger den mest spesifikke håndtereren. Hvis ResourceNotFoundException extends RuntimeException, har en håndterer for ResourceNotFoundException prioritet over en for RuntimeException.

Hurtigsjekk

Hvilken annotasjon markerer en metode som skal håndtere en bestemt exception-type globalt?

Oppsummering

Bruk @RestControllerAdvice + @ExceptionHandler for å sentralisere feilhåndtering. Returner ResponseEntity med en konsekvent feilstruktur. Håndter validering (MethodArgumentNotValidException) og begrensninger (ConstraintViolationException) separat. Logg 4xx som WARN og 5xx som ERROR.

Gratis å komme i gang

Lær deg Java med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
104
Leksjoner
374

Ofte stilte spørsmål

Er leksjonen «Global unntakshåndtering med @ControllerAdvice» gratis?

Ja – hele teksten i «Global unntakshåndtering med @ControllerAdvice» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Global unntakshåndtering med @ControllerAdvice»?

Sentraliser unntakshåndteringen på tvers av alle kontrollere med @ExceptionHandler og @ControllerAdvice. Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Java Academy?

Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Global unntakshåndtering med @ControllerAdvice»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?

Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Bean-validering: @NotNull, @Size, @Pattern
  2. Egendefinerte constraint-annotasjoner
  3. Global unntakshåndtering med @ControllerAdvice
  4. RFC 7807 Problem Details og konsistente feilsvar
← Tilbake til Java Academy