Global felhantering med @ControllerAdvice
Centralisera översättningen av undantag till rena HTTP-svar med @ExceptionHandler och @ControllerAdvice.
Global felhantering med @ControllerAdvice är en gratis lektion i Spring Boot 4 – komplett guide på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Spring Boot 4 – komplett guide, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
Varför centralisera undantagshanteringen?
När något går fel i ett Spring Boot REST API bör klienten få ett rent och förutsägbart HTTP-svar, inte en rå stack trace.
Utan en strategi slutar det ofta med att Ni sprider try/catch-block över varje controller-metod och upprepar samma logik för att bygga JSON-svar gång på gång.
- Inkonsekventa statuskoder för samma feltyp
- Duplicerad utformning av felsvar
- Läckta interna detaljer (stack traces, SQL) till klienter
Global undantagshantering löser detta genom att översätta undantag till HTTP-svar på en enda plats.
Byggstenen @ExceptionHandler
Den centrala annoteringen är @ExceptionHandler. Den markerar en metod som hanterar en specifik undantagstyp som kastas under behandlingen av en begäran.
Om den placeras i en controller fångar den endast undantag som kastas av den controllerns handler-metoder.
Metodens parameter anger vilket undantag den hanterar, och returvärdet blir HTTP-svaret.
@RestController
public class ProductController {
@GetMapping("/products/{id}")
public Product getProduct(@PathVariable Long id) {
throw new ProductNotFoundException(id);
}
@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<String> handleNotFound(ProductNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}
}Från lokal till global med @ControllerAdvice
En lokal @ExceptionHandler omfattar endast en controller. Om Ni vill dela handlers i hela applikationen flyttar Ni dem till en klass som annoterats med @ControllerAdvice.
@ControllerAdvice är en specialisering av @Component. Spring registrerar dess @ExceptionHandler-metoder globalt, så alla controllers som kastar ett matchande undantag hanteras där.
För REST API:er bör Ni föredra @RestControllerAdvice, som kombinerar @ControllerAdvice med @ResponseBody så att returvärden automatiskt serialiseras till JSON.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<String> handleNotFound(ProductNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}
}Ett konsekvent felsvar
Att returnera en rå sträng räcker sällan. Klienter behöver ett strukturerat och förutsägbart JSON-objekt som de kan tolka.
Definiera ett litet error response record som alla handlers returnerar. Detta är vanlig Java och kräver inget ramverk, så det är helt fristående.
Spring serialiserar detta record till JSON när det returneras från en metod i @RestControllerAdvice.
import java.time.Instant;
public record ApiError(
Instant timestamp,
int status,
String error,
String message,
String path) {
}
public class Demo {
public static void main(String[] args) {
ApiError err = new ApiError(
Instant.parse("2026-01-01T10:15:30Z"),
404,
"Not Found",
"Product 42 not found",
"/products/42");
System.out.println(err);
}
}Returnera strukturerade fel med ResponseEntity
Kombinera nu recordet ApiError med Er globala handler. Skapa en ResponseEntity som innehåller både rätt statuskod och den strukturerade svarskroppen.
Använd den injicerade HttpServletRequest för att fånga sökvägen till begäran, vilket är användbart vid felsökning på klientsidan.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<ApiError> handleNotFound(
ProductNotFoundException ex, HttpServletRequest request) {
ApiError error = new ApiError(
Instant.now(),
HttpStatus.NOT_FOUND.value(),
HttpStatus.NOT_FOUND.getReasonPhrase(),
ex.getMessage(),
request.getRequestURI());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
}Mappa status med @ResponseStatus
Om en handler alltid returnerar samma status och Ni inte behöver anpassade headers kan Ni helt utelämna ResponseEntity.
Annotera handler-metoden med @ResponseStatus(...) och returnera svarskroppen direkt. Spring tillämpar statuskoden åt Er.
Detta håller enkla handlers korta, men använd ResponseEntity när Ni behöver dynamiska statuskoder eller headers.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ProductNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiError handleNotFound(ProductNotFoundException ex, HttpServletRequest req) {
return new ApiError(Instant.now(), 404, "Not Found",
ex.getMessage(), req.getRequestURI());
}
}Hantera valideringsfel
När en @Valid-märkt request body inte klarar Bean Validation kastar Spring MethodArgumentNotValidException. Som standard blir JSON-svaret omfattande och svåröverskådligt.
Överskugga hanteringen i Er advice för att returnera en ren karta över fältfel. Varje FieldError innehåller namnet på det felaktiga fältet och valideringsmeddelandet.
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> handleValidation(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) {
errors.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return errors;
}En handler för flera undantag
@ExceptionHandler accepterar en array av undantagsklasser, så en enda metod kan hantera flera relaterade typer som ska mappas till samma status.
Det undviker duplicerad kod när exempelvis flera olika undantag för "felaktig indata" alla ska bli 400 Bad Request.
@ExceptionHandler({
IllegalArgumentException.class,
IllegalStateException.class,
ConstraintViolationException.class
})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiError handleBadRequest(RuntimeException ex, HttpServletRequest req) {
return new ApiError(Instant.now(), 400, "Bad Request",
ex.getMessage(), req.getRequestURI());
}Ordning vid undantagsupplösning
När ett undantag kastas väljer Spring den mest specifika matchande @ExceptionHandler.
- En handler för den exakta typen vinner över en handler för dess superklass.
- Lokala handlers i controllern prioriteras framför globala handlers i
@ControllerAdvice. - Om två handlers är lika specifika rapporterar Spring ett tvetydighetsfel vid uppstart.
Denna ordning gör det möjligt att tillhandahålla en bred reservhantering och samtidigt skriva över specifika fall.
En säker reservhantering för allt
Definiera alltid en sista reservhandler för Exception.class. Den fångar allt som Ni inte uttryckligen har mappat och förhindrar att interna detaljer läcker ut.
Returnera ett generiskt 500 Internal Server Error med ett säkert meddelande och logga det verkliga undantaget på serversidan för vidare undersökning.
Lägg aldrig det råa undantagsmeddelandet eller stack tracen i klientsvaret för oväntade fel.
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiError handleAny(Exception ex, HttpServletRequest req) {
log.error("Unhandled exception at {}", req.getRequestURI(), ex);
return new ApiError(Instant.now(), 500, "Internal Server Error",
"An unexpected error occurred", req.getRequestURI());
}Avgränsa och utöka ramverkets basklass
Ni kan avgränsa en advice till en delmängd av controllers med attribut som @RestControllerAdvice(basePackages = "com.shop.api") eller assignableTypes = {...}. En advice utan avgränsning gäller överallt.
För full kontroll över Springs inbyggda Spring MVC-undantag (saknade parametrar, oläsbara request bodies, mediatyper som inte stöds) kan Ni ärva från ResponseEntityExceptionHandler och överskugga dess skyddade metoder. Klassen deklarerar redan handlers för standardundantagen i MVC.
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<ApiError> handleNotFound(
ProductNotFoundException ex, HttpServletRequest req) {
ApiError error = new ApiError(Instant.now(), 404, "Not Found",
ex.getMessage(), req.getRequestURI());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
}Snabb kontroll
Ni har ett REST API. Ni vill att valideringsfel och fel för resurser som inte hittas ska ge konsekventa JSON-svar och korrekta statuskoder för alla controllers, på en enda plats. Vilket är det idiomatiska tillvägagångssättet i Spring Boot?
Sammanfattning
Ni har lärt Er att centralisera undantagshanteringen i Spring Boot:
@ExceptionHandlermappar en undantagstyp till ett HTTP-svar. På egen hand är den lokal för controllern.@RestControllerAdviceregistrerar handlers globalt och serialiserar returvärden till JSON.- Returnera ett konsekvent error record (status, meddelande, sökväg och tidsstämpel) för förutsägbara klienter.
- Använd
ResponseEntityför dynamiska statuskoder och headers, eller@ResponseStatusför fasta värden. - Hantera
MethodArgumentNotValidExceptionför rena valideringsfel, gruppera relaterade undantag och lägg alltid till en reservhantering förException.classsom döljer interna detaljer.
Resultatet blir konsekventa, säkra och underhållbara felsvar i hela Ert API.
Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 21
- Lektioner
- 84
Vanliga frågor
Är lektionen ”Global felhantering med @ControllerAdvice” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Spring Boot 4 – komplett guide, inklusive ”Global felhantering med @ControllerAdvice”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
Vad lär jag mig i ”Global felhantering med @ControllerAdvice”?
Centralisera översättningen av undantag till rena HTTP-svar med @ExceptionHandler och @ControllerAdvice. Ni övar på Spring Boot 4 – komplett guide med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Spring Boot 4 – komplett guide?
Du behöver inga förkunskaper. Utbildningen i Spring Boot 4 – komplett guide på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Global felhantering med @ControllerAdvice”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Spring Boot 4 – komplett guide-lektionen?
Ja. Varje Spring Boot 4 – komplett guide-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Bean Validation-begränsningar och constraint-grupper
- Skapa egna constraint-annoteringar
- Global felhantering med @ControllerAdvice
- RFC 7807-svar med problemdetaljer