{"componentChunkName":"component---src-templates-blog-post-js","path":"/springboot/스프링-부트-controller-advice를-활용한-exception-처리/","result":{"data":{"site":{"siteMetadata":{"title":"Bottlehs Tech Blog","description":"웹·앱·AI 개발자 전병훈(bottlehs)의 기술 블로그. AI·LLM, JavaScript·Vue, Spring Boot, 알고리즘, 블록체인 실무 가이드를 다룹니다","siteUrl":"https://www.bottlehs.dev","author":{"name":"Jeon Byung Hun","summary":"개발을 즐기는 bottlehs - Engineer, MS, AI, FE, BE, OS, IOT, Blockchain, 설계, 테스트"},"social":{"github":"bottlehs","codepen":"bottlehs"}}},"markdownRemark":{"id":"affecce9-ec2d-5973-be35-7bc525f3bf25","excerpt":"스프링 부트 ControllerAdvice를 활용한 Exception…","html":"<p><img src=\"/assets/springboot.png\" alt=\"스프링 부트 ControllerAdvice를 활용한 Exception 처리\" title=\"스프링 부트 ControllerAdvice를 활용한 Exception 처리\"></p>\n<p>오류 처리는 프로그램을 개발하는데 있어서 매우 큰 부분을 차지한다. 오류를 예측해서 비정상적인 상황이 발생하지 않게 하는 것은 중요하다. 과하다할 만큼 상세하고 다양하게 예외를 잡아 처리해준다면, 클라이언트도 그렇고 서버도 그렇고 더 안정적인 프로그램이 될 수 있게 도와준다. 예외 처리에 집중 하다 보면, 비즈니스 로직에 집중하기 어렵고, 비즈니스 로직과 관련된 코드보다 예외 처리를 위한 코드가 더 많아지는 경우도 생기게 된다. 이런 문제를 조금이라도 개선하기 위해 @ExceptionHandler와 @ControllerAdvice를 사용한다.</p>\n<h2 id=\"controlleradvice-란\" style=\"position:relative;\"><a href=\"#controlleradvice-%EB%9E%80\" aria-label=\"controlleradvice 란 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>@ControllerAdvice 란?</h2>\n<p>@Controller나 @RestController에서 발생한 예외를 한 곳에서 관리하고 처리할 수 있게 도와주는 어노테이션이다. 즉 스프링에서 예외처리를 전역적으로 핸들링하기 위해 @ControllerAdvicde 어노테이션을 사용할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@ControllerAdvice</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">ControllerExceptionHandler</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">Logger</span> log <span class=\"token operator\">=</span> <span class=\"token class-name\">LoggerFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">getLogger</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">ControllerExceptionHandler</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token annotation punctuation\">@ExceptionHandler</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">NoLoginException</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">public</span> <span class=\"token class-name\">String</span> <span class=\"token function\">noLoginException</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Exception</span> e<span class=\"token punctuation\">,</span> <span class=\"token class-name\">Model</span> model<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        model<span class=\"token punctuation\">.</span><span class=\"token function\">addAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"errorMessage\"</span><span class=\"token punctuation\">,</span> e<span class=\"token punctuation\">.</span><span class=\"token function\">getMessage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string\">\"user/login_failed\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>위는 NoLoginException이 발생한 경우에 해당 에러메세지를 표시하는 페이지를 리턴해주도록 구현한 코드다. ControllerAdvice를 사용해서 아래의 형태로 응답을 줄수도 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@ExceptionHandler</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">AlreadyIncludeSharedNoteBookException</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">public</span> <span class=\"token class-name\">ResponseEntity</span> <span class=\"token function\">alreadyIncludeShardNoteBook</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">AlreadyIncludeSharedNoteBookException</span> exception<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    log<span class=\"token punctuation\">.</span><span class=\"token function\">debug</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"AlreadyIncludeSharedNoteBookException is happened!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">ErrorDetails</span> errorDetails <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ErrorDetails</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> exception<span class=\"token punctuation\">.</span><span class=\"token function\">getMessage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token class-name\">ResponseEntity</span><span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">HttpStatus</span><span class=\"token punctuation\">.</span><span class=\"token constant\">FORBIDDEN</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">body</span><span class=\"token punctuation\">(</span>errorDetails<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>@RestControllerAdvice는 @ControllerAdvice+@ResponseBody의 역할을 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@RestControllerAdvice</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">RestExceptionHandler</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token annotation punctuation\">@ResponseStatus</span><span class=\"token punctuation\">(</span>value <span class=\"token operator\">=</span> <span class=\"token class-name\">HttpStatus</span><span class=\"token punctuation\">.</span><span class=\"token constant\">UNAUTHORIZED</span><span class=\"token punctuation\">)</span>\n  <span class=\"token annotation punctuation\">@ExceptionHandler</span><span class=\"token punctuation\">(</span>value <span class=\"token operator\">=</span> <span class=\"token class-name\">UnAuthorizedException</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">public</span> <span class=\"token class-name\">Object</span> <span class=\"token function\">handleUnAutorizedException</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">UnAuthorizedException</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Object</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span><span class=\"token function\">getMessage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>404 에러 같은 경우는 DispatcherServlet에서 발생하는 에러라서 핸들링 할 수 없다.</p>","tableOfContents":"<ul>\n<li><a href=\"/springboot/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-controller-advice%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-exception-%EC%B2%98%EB%A6%AC/#controlleradvice-%EB%9E%80\">@ControllerAdvice 란?</a></li>\n</ul>","wordCount":{"words":131},"fields":{"slug":"/springboot/스프링-부트-controller-advice를-활용한-exception-처리/","image":"/assets/springboot.png","faq":[]},"frontmatter":{"title":"스프링 부트 ControllerAdvice를 활용한 Exception 처리","date":"2021년 4월 8일","dateISO":"2021-04-08T21:29:29.537Z","updatedISO":null,"category":"springboot","description":"오류 처리는 프로그램을 개발하는데 있어서 매우 큰 부분을 차지한다. 오류를 예측해서 비정상적인 상황이 발생하지 않게 하는 것은 중요하다. 과하다할 만큼 상세하고 다양하게 예외를 잡아 처리해준다면, 클라이언트도 그렇고 서버도 그렇고 더 안정적인 프로그램이 될 수 있게 도와준다. 예외 처리에 집중 하다 보면, 비즈니스 로직에 집중하기 어렵고, 비즈니스 로직과 관련된 코드보다 예외 처리를 위한 코드가 더 많아지는 경우도 생기게 된다. 이런 문제를 조금이라도 개선하기 위해 @ExceptionHandler와 @ControllerAdvice를 사용한다.","tags":["스프링","스프링부트","Spring","SpringBoot","Java","프레임워크","스프링부트구조","아키텍쳐","ControllerAdvice"]}}},"pageContext":{"slug":"/springboot/스프링-부트-controller-advice를-활용한-exception-처리/","previous":{"fields":{"slug":"/springboot/스프링-부트-API-인터페이스-및-결과-데이터-구조-설계/"},"frontmatter":{"title":"스프링 부트 API 인터페이스 및 결과 데이터 구조 설계","tags":["스프링","스프링부트","Spring","SpringBoot","Java","프레임워크","스프링부트구조","아키텍쳐"]}},"next":{"fields":{"slug":"/springboot/스프링-부트-message-source를-활용한-exception-처리/"},"frontmatter":{"title":"스프링 부트 MessageSource를 활용한 Exception 처리","tags":["스프링","스프링부트","Spring","SpringBoot","Java","프레임워크","스프링부트구조","아키텍쳐","MessageSource"]}}}},"staticQueryHashes":["213619243","3262363727"]}