일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- github
- MySQL
- catalina log
- log4j profile
- log4j2
- Spring Boot
- template
- Spring Security
- git
- oracle
- ubuntu
- Gradle
- hikari
- Spring
- hikaricp
- Java
- between 날짜
- bitbucket
- datasource
- STS
- oracle between
- between date
- ORACLE CLOUD
- 배열스트링
- 라즈베리파이
- mybatis
- intellij
- python 개발환경
- springboot
- Linux
Archives
- Today
- Total
반응형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- github
- MySQL
- catalina log
- log4j profile
- log4j2
- Spring Boot
- template
- Spring Security
- git
- oracle
- ubuntu
- Gradle
- hikari
- Spring
- hikaricp
- Java
- between 날짜
- bitbucket
- datasource
- STS
- oracle between
- between date
- ORACLE CLOUD
- 배열스트링
- 라즈베리파이
- mybatis
- intellij
- python 개발환경
- springboot
- Linux
Archives
- Today
- Total
파워노트
[ skeleton ] spring boot exception ( 예외 처리 ) 본문
반응형
Exception 처리 .
- spring boot에서의 Exception 처리는 복잡하게 파고들면 복잡하지만 간단하게 생각하면 또 간단하다. ( 당연한 말이겠지만 )
- Exception 은 크게
- 컴파일 시점에 발생하는 예외를 Exception(일반예외) 라고 하고,
- 프로그램 실행시에 발생하는 예외를 RuntimeException(실행예외) 라고 합니다.
- 즉, 예외가 발생하는 시점에 프로그램이 실행 전 후 상태에 따라 이를 구분하면 됩니다. 컴파일 시 예외처리를 확인하는 차이일 뿐, 두 가지 예외는 모두 예외 처리가 필요하다. 자바에서는 예외를 클래스로 관리한다. 모든 예외 클래스들은 java.lang.Exception 클래스를 상속받는다.
ExceptionHandler
- @ControllerAdvice, @RestControllerAdvice 에서 controller 내부에서 처리되다가 오류나는 사항에 대해서 Handling 할 수 있다.
- Web Page Handle
-
@ControllerAdvice(basePackages = "com.powernote.skeleton.controller") public class WebExceptionHandler { // error.html이 있는경우는 해당 페이지로 이동하고 없는경우 error/4xx.html error/5xx.html 로 찾아 status 를 찾아 이동한다. // page가 있는경우( 404 등 ) BasicErrorController 를 통하지 않는다. @ExceptionHandler(value = Exception.class) public ModelAndView pageHandlerException(HttpServletRequest request, Model model, Exception e) { String defaultError = MessageType.ERROR_TYPE_000.toString(); log.info("WebExceptionHandler "); model.addAttribute("timestamp", new Date().toString() ); model.addAttribute( "status", String.valueOf( HttpStatus.INTERNAL_SERVER_ERROR.value() ) ); model.addAttribute( "error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() ); model.addAttribute( "errorCode", defaultError ); model.addAttribute( "message", MessageUtil.getMessage( defaultError ) ); // MessageUtil을 통한 메시지 전달 처리 적용 필요. model.addAttribute( "path", request.getRequestURI() ); model.addAttribute( "exception", Exception.class.getName() ); log.info( "[ Exception, " + String.valueOf( HttpStatus.INTERNAL_SERVER_ERROR.value() ) + MessageUtil.getMessage( defaultError ) + "]"); return new ModelAndView("/error/error"); } }
- API Handler
@RestControllerAdvice(annotations = RestController.class) public class ApiExceptionHandler { // 기본 에러 처리 @ExceptionHandler(Exception.class) public ResponseEntity<ErrorRes> exception(HttpServletRequest request, Exception e) { String defaultError = MessageType.ERROR_TYPE_000.toString(); ErrorRes response = ErrorRes.builder().build(); response.setTimestamp( new Date().toString() ); response.setStatus( String.valueOf( HttpStatus.INTERNAL_SERVER_ERROR.value() ) ); response.setError( HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() ); response.setErrorCode( defaultError ); response.setMessage( MessageUtil.getMessage( defaultError ) ); response.setPath( request.getRequestURI() ); return new ResponseEntity<>(response, CommonUtil.getHeader(), HttpStatus.INTERNAL_SERVER_ERROR); } }
- controller 내부 구현시 오류 발생하면 해당 mvc controll 인경우 WebExceptionHandler 의 Handler에서 처리 되며, API 요청인경우 ApiExceptionHandler 에서 처리 된다 .
- 404 error , 403 error 등과 같이 controller 내부에 까지 오기 전에 servlet 단에서 오류가 난경우의 처리를 위해 getErrorAttributes() 메소드를 override 해서 구현한다.
@Component public class ExceptionServletAttributes extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { Integer status = (Integer) webRequest.getAttribute("javax.servlet.error.status_code", RequestAttributes.SCOPE_REQUEST); if (status != HttpStatus.NOT_FOUND.value() && status != HttpStatus.FORBIDDEN.value() ) { return super.getErrorAttributes(webRequest, options); } Map<String, Object> errorAttributes = new HashMap<>(); if( status == HttpStatus.NOT_FOUND.value() ){ errorAttributes.put("timestamp", new Date().toString() ); errorAttributes.put("status", HttpStatus.NOT_FOUND.value()); errorAttributes.put("error", "404"); errorAttributes.put("message", MessageType.ERROR_PAGE_404.getMessage() ); String attributeNames = String.valueOf(webRequest.getAttribute("javax.servlet.forward.request_uri", 0)) ; errorAttributes.put("path", attributeNames ); errorAttributes.put("errorCode", MessageType.ERROR_PAGE_404.toString() ); errorAttributes.put("exception", ""); } else if ( status == HttpStatus.FORBIDDEN.value() ) { errorAttributes.put("timestamp", new Date().toString() ); errorAttributes.put("status", HttpStatus.FORBIDDEN.value()); errorAttributes.put("error", "403"); errorAttributes.put("message", MessageType.ERROR_PAGE_403.getMessage() ); String attributeNames = String.valueOf(webRequest.getAttribute("javax.servlet.forward.request_uri", 0)) ; errorAttributes.put("path", attributeNames ); errorAttributes.put("errorCode", MessageType.ERROR_PAGE_403.toString() ); errorAttributes.put("exception", ""); } return errorAttributes; } }
error page 구현
- spring boot에서의 Error 처리설정 및 경로 설정은 BasicErrorController 에서 설정된다. 기본값은 "/error"
- 기본적으로 여러 Error Page의 경로는 /error 이다 . Http status code 에 따라 페이지가 호출된다.
따라서 401.html, 403.html, 404.html 등과 같이 페이지를 구현하여 폴더에 준비해두면 된다.
- 404 Error 페이지 예시
- github : https://github.com/powerkkim/skeleton/tree/50c2435428a64909ba2f2ff8696eb127dc68c10e
마무리 .
- 개인적으로 Exception 처리의 정리가 spring boot 개발에서는 중요한 부분으로 생각된다.
- 물론 완벽한 코드를 처리하면 좋지만 언제나 오류는 발생할 수 있기에 합당하면서도 에러확인이 편하게 도출되고 표현되도록 하는것은 매우 중요하다.
반응형
'spring boot' 카테고리의 다른 글
security 를 이용한 로그인시 authentication and session (0) | 2022.01.07 |
---|---|
이유 없이 controller 유입이 두번씩 될때.. favicon 404 (0) | 2022.01.07 |
[ skeleton ] spring boot security ( web login ) (0) | 2021.11.26 |
[ skeleton ] thymeleaf 기본 레이아웃 설정. feature Admin LTE (0) | 2021.11.21 |
[ skeleton ] thymeleaf 페이지수정시 재시작없이 리로딩 ( Local 작업시 설정. ) (0) | 2021.11.17 |
Comments