{"id":278,"date":"2026-03-10T15:04:17","date_gmt":"2026-03-10T14:04:17","guid":{"rendered":"https:\/\/test.craftcode.be\/repetitieve-code-wegwerken-met-een-vaak-vergeten-annotatie\/"},"modified":"2026-06-04T12:04:40","modified_gmt":"2026-06-04T10:04:40","slug":"repetitieve-code-wegwerken-met-een-vaak-vergeten-annotatie","status":"publish","type":"post","link":"https:\/\/craftcode.be\/nl\/repetitieve-code-wegwerken-met-een-vaak-vergeten-annotatie\/","title":{"rendered":"Repetitieve code wegwerken met een vaak vergeten annotatie"},"content":{"rendered":"\n<p>In deze blog focussen we op exception handling binnen Spring-applicaties en hoe een vaak vergeten annotatie helpt om repetitieve code drastisch te verminderen. <\/p>\n\n<h2 class=\"wp-block-heading has-primary-color has-text-color has-link-color wp-elements-50cfb71e98c2583f1858cea59f7649b1\">Repetitie verwijderen<\/h2>\n\n<p>Om exceptions af te handelen, wordt vaak gebruikgemaakt van een try\/catch in de controller zodat gebruikers ge\u00efnformeerd worden wanneer de API een probleem tegenkomt. Dat werkt prima, maar zodra applicaties groeien en er meer exceptions bijkomen, raken controllers snel overvol.<br\/><br\/>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.<br\/><br\/>Belangrijk om op te merken: bij deze aanpak moet voor elk endpoint een gelijkaardige catch geschreven worden.     <\/p>\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"673\" height=\"233\" src=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_10.png\" alt=\"\" class=\"wp-image-136\" srcset=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_10.png 673w, https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_10-300x104.png 300w\" sizes=\"auto, (max-width: 673px) 100vw, 673px\" \/><\/figure>\n\n<p><span style=\"color: color(srgb 0.00392157 0.0117647 0.14902 \/ 0.8);\">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 <\/span><a href=\"https:\/\/www.baeldung.com\/exception-handling-for-rest-with-spring\" target=\"_blank\" rel=\"noopener\">onderwerp<\/a>, <span style=\"color: color(srgb 0.00392157 0.0117647 0.14902 \/ 0.8);\">maar onderstaande aanpak is gebaseerd op een combinatie van verschillende technieken en tutorials. Uiteraard zijn verdere optimalisaties altijd mogelijk.<\/span><\/p>\n\n<h2 class=\"wp-block-heading has-primary-color has-text-color has-link-color wp-elements-e05c411384fe29e8a241ab455dbbfa6e\">ExceptionHandler<\/h2>\n\n<p>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.<br\/>In dit voorbeeld wordt een MessageBusinessException afgehandeld, maar andere exceptions kunnen eenvoudig toegevoegd worden.<br\/><br\/>De belangrijkste component hier is de annotatie @ControllerAdvice.<br\/><br\/>Met @ControllerAdvice kan globale code toegepast worden op meerdere controllers tegelijk. Exceptions worden centraal afgehandeld over de volledige applicatie heen via \u00e9\u00e9n globale handling component. Op basis van de business exception wordt vervolgens een foutresponse teruggestuurd.       <\/p>\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"850\" height=\"592\" src=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_4.png\" alt=\"\" class=\"wp-image-135\" srcset=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_4.png 850w, https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_4-300x209.png 300w, https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_4-768x535.png 768w\" sizes=\"auto, (max-width: 850px) 100vw, 850px\" \/><\/figure>\n\n<p><span style=\"color: color(srgb 0.00392157 0.0117647 0.14902 \/ 0.8);\">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 &#8211; behalve mogelijk het verwijderen van alle try\/catch-constructies die vervangen worden door deze centrale aanpak. <\/span><\/p>\n\n<h2 class=\"wp-block-heading has-primary-color has-text-color has-link-color wp-elements-4b40e596315cb79e0fae40e6c15274d5\">Exceptions beheren met key-value pairs<\/h2>\n\n<p>Voor het opbouwen van foutmeldingen kan gebruikgemaakt worden van een helpermethode zoals createErrorResponse. Deze methode geeft de HttpStatus en response terug.<br\/> <br\/>De status en response worden opgehaald uit de<a href=\"https:\/\/craftcode.be\/mowing-repetitive-code-with-an-often-forgotten-annotation\/##Dictionary\"> ApiErrorDictionar<\/a>y, 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.<br\/> <br\/>Het voordeel van deze dictionary is het standaardiseren van responses die op meerdere plaatsen binnen de applicatie terugkomen.<br\/> <br\/>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 &#8211; iets wat in complexe applicaties snel kan oplopen    <\/p>\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"846\" height=\"308\" src=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_11.png\" alt=\"\" class=\"wp-image-137\" srcset=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_11.png 846w, https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_11-300x109.png 300w, https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_11-768x280.png 768w\" sizes=\"auto, (max-width: 846px) 100vw, 846px\" \/><\/figure>\n\n<h2 class=\"wp-block-heading has-primary-color has-text-color has-link-color wp-elements-a58fb843752b638d1a7bf2be0a34939e\">MessageBusinessException<\/h2>\n\n<p>Er is nog \u00e9\u00e9n extra klasse nodig.<br\/><br\/>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.<br\/><br\/>Vaak wordt zo\u2019n business exceptionklasse per feature voorzien.<br\/>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.<br\/><br\/>De MessageBusinessException ziet er ongeveer als volgt uit.     <\/p>\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"890\" height=\"126\" src=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_3.png\" alt=\"\" class=\"wp-image-134\" srcset=\"https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_3.png 890w, https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_3-300x42.png 300w, https:\/\/craftcode.be\/app\/uploads\/2026\/03\/CraftCode_Blog_exception_handling_3-768x109.png 768w\" sizes=\"auto, (max-width: 890px) 100vw, 890px\" \/><\/figure>\n\n<h2 class=\"wp-block-heading has-primary-color has-text-color has-link-color wp-elements-0e6707d11dfe06fdb74b46666a58eeb3\">Flow<\/h2>\n\n<p>Met deze structuur wordt het eenvoudig om nieuwe exceptions toe te voegen.<br\/><br\/>Daarvoor zijn slechts enkele stappen nodig:<br\/>\u00b7 de business exceptionklasse uitbreiden of aanpassen, <br\/>\u00b7 een nieuwe key\/value-pair toevoegen aan de ApiErrorDictionary, <br\/>\u00b7 en de exception gooien vanuit de juiste service. <br\/><br\/>Een eenvoudige aanpak die op termijn heel wat repetitief werk vermijdt.  <\/p>\n\n<h2 class=\"wp-block-heading has-primary-color has-text-color has-link-color wp-elements-5f80eacb063967704316ddd6659bf00d\">Git<\/h2>\n\n<p>Deze tutorial is misschien wat kort, maar de volledige code is terug te vinden op het <a href=\"https:\/\/github.com\/CraftCodeBE\/hellospringexceptionhandling\" target=\"_blank\" rel=\"noopener\">GitHub-account<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Leesbare code blijft \u00e9\u00e9n van de grootste uitdagingen binnen softwareontwikkeling. Functionaliteit snel opleveren krijgt vaak prioriteit, terwijl structuur en onderhoudbaarheid pas later aandacht krijgen. Begrijpelijk &#8211; werkende software is belangrijk. Maar hoe groter een applicatie wordt, hoe belangrijker duidelijke en onderhoudbare code wordt.<\/p>\n<p>Gelukkig bestaan er technieken en tools die helpen om tot clean en schaalbare Java-code te komen.      <\/p>\n","protected":false},"author":1,"featured_media":277,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[55],"tags":[56],"class_list":["post-278","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-technologie"],"acf":[],"_links":{"self":[{"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/posts\/278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/comments?post=278"}],"version-history":[{"count":1,"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/posts\/278\/revisions"}],"predecessor-version":[{"id":279,"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/posts\/278\/revisions\/279"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/media\/277"}],"wp:attachment":[{"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/media?parent=278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/categories?post=278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/craftcode.be\/nl\/wp-json\/wp\/v2\/tags?post=278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}