Blog
Repetitieve code wegwerken met een vaak vergeten annotatie
Leesbare code blijft één van de grootste uitdagingen binnen softwareontwikkeling. Functionaliteit snel opleveren krijgt vaak prioriteit, terwijl structuur en onderhoudbaarheid pas later aandacht krijgen. Begrijpelijk - werkende software is belangrijk. Maar hoe groter een applicatie wordt, hoe belangrijker duidelijke en onderhoudbare code wordt.<br/><br/>Gelukkig bestaan er technieken en tools die helpen om tot clean en schaalbare Java-code te komen.
In deze blog focussen we op exception handling binnen Spring-applicaties en hoe een vaak vergeten annotatie helpt om repetitieve code drastisch te verminderen.
Repetitie verwijderen
Om exceptions af te handelen, wordt vaak gebruikgemaakt van een try/catch in de controller zodat gebruikers geïnformeerd worden wanneer de API een probleem tegenkomt. Dat werkt prima, maar zodra applicaties groeien en er meer exceptions bijkomen, raken controllers snel overvol.
Onderstaande aanpak toont een basisimplementatie van exception handling. Wanneer er iets fout loopt tijdens het ophalen van berichten, voorziet het Spring Framework standaard al een mechanisme om een response terug te sturen. Je kan hiervoor de standaardboodschap gebruiken via e.getMessage(), of zelf een aangepaste boodschap voorzien.
Belangrijk om op te merken: bij deze aanpak moet voor elk endpoint een gelijkaardige catch geschreven worden.

Zoals eerder aangehaald, kost repetitieve code in grotere applicaties met veel controllers en CRUD-operaties enorm veel tijd. Daarom voorziet Spring een meer centrale manier van exception handling. Er bestaat al veel documentatie over dit onderwerp, maar onderstaande aanpak is gebaseerd op een combinatie van verschillende technieken en tutorials. Uiteraard zijn verdere optimalisaties altijd mogelijk.
ExceptionHandler
De eerste stap is het voorzien van een klasse die exceptions afhandelt. Naast een constructor die een dictionary initialiseert, bevat deze klasse methodes die specifieke exceptions verwerken.
In dit voorbeeld wordt een MessageBusinessException afgehandeld, maar andere exceptions kunnen eenvoudig toegevoegd worden.
De belangrijkste component hier is de annotatie @ControllerAdvice.
Met @ControllerAdvice kan globale code toegepast worden op meerdere controllers tegelijk. Exceptions worden centraal afgehandeld over de volledige applicatie heen via één globale handling component. Op basis van de business exception wordt vervolgens een foutresponse teruggestuurd.

In dit voorbeeld wordt enkel een MessageBusinessException gebruikt, maar in complexere applicaties kunnen uiteraard meerdere exceptiontypes toegevoegd worden. In de controller zelf hoeft bijna niets meer te gebeuren – behalve mogelijk het verwijderen van alle try/catch-constructies die vervangen worden door deze centrale aanpak.
Exceptions beheren met key-value pairs
Voor het opbouwen van foutmeldingen kan gebruikgemaakt worden van een helpermethode zoals createErrorResponse. Deze methode geeft de HttpStatus en response terug.
De status en response worden opgehaald uit de ApiErrorDictionary, wat in essentie een onveranderbare map (unmodifiable map) is. Daarbij wordt gebruikgemaakt van een ApiError-model dat in dit voorbeeld enkel een string bevat om een foutboodschap terug te sturen.
Het voordeel van deze dictionary is het standaardiseren van responses die op meerdere plaatsen binnen de applicatie terugkomen.
In plaats van een onveranderbare map te gebruiken, zouden deze key-value pairs ook uit een database gehaald kunnen worden. Het doel blijft hetzelfde: repetitieve code zoveel mogelijk elimineren – iets wat in complexe applicaties snel kan oplopen

MessageBusinessException
Er is nog één extra klasse nodig.
Een exception wordt vaak in de service gegooid en reist vervolgens via de controller door naar de gebruiker. Om custom exceptions te kunnen gebruiken, moet een eigen klasse geschreven worden die RuntimeException uitbreidt.
Vaak wordt zo’n business exceptionklasse per feature voorzien.
In de demo-code maakt deze deel uit van het service package, maar het is evengoed mogelijk om de code per feature te structureren en per feature een eigen business exceptionklasse te voorzien.
De MessageBusinessException ziet er ongeveer als volgt uit.

Flow
Met deze structuur wordt het eenvoudig om nieuwe exceptions toe te voegen.
Daarvoor zijn slechts enkele stappen nodig:
· de business exceptionklasse uitbreiden of aanpassen,
· een nieuwe key/value-pair toevoegen aan de ApiErrorDictionary,
· en de exception gooien vanuit de juiste service.
Een eenvoudige aanpak die op termijn heel wat repetitief werk vermijdt.
Git
Deze tutorial is misschien wat kort, maar de volledige code is terug te vinden op het GitHub-account.
< Keep reading />
More from our team
Explore more insights, tips, and deep dives from the CraftCode team.
Aan de slag!
Klaar om jouw visie werkelijkheid te maken?
Laten we iets bouwen waar je bedrijf écht mee verder kan.