FireDrago

[Spring] 스프링 예외처리와 오류페이지 본문

프로그래밍/Spring

[Spring] 스프링 예외처리와 오류페이지

화이용 2024. 2. 17. 14:50

<스프링부트 예외처리>

 

스프링 부트는 컨트롤러에서 예외가 처리되지 않고, WAS까지 던져진 경우 위와같이 예외를 처리한다.

예외가 발생하거나, response.sendError() 가 호출되면 WAS는 지정된 오류경로로 다시 요청을 보낸다.

스프링 부트는 기본 에러 경로 ("/error")를 제공하고 이에따른 BasicErrorController를 기본적으로 제공한다.

따라서 개발자는 BasicErrorController에 정의된 View 우선순위에 맞춰 에러페이지를 만들어 주기만 하면 된다.

우선순위는 다음과 같다.

1. 뷰 템플릿
resources/templates/error/500.html
resources/templates/error/5xx.html
2. 정적 리소스( static , public )
resources/static/error/400.html
resources/static/error/404.html
resources/static/error/4xx.html
3. 적용 대상이 없을 때 뷰 이름( error )
resources/templates/error.html

 

다음과 같은 경로에 에러페이지를 설정한뒤 에러를 호출하면, 별다른 설정없이도 404.html이 호출되는 것을 볼 수 있다.

 

 

<BasicErrorController 제공 정보>

BasicErrorController는 뷰 템플릿에 에러에 관한 정보를 Model에 담아 전달하고 뷰 템플릿은 이를 출력할 수 있다.

application.properties 를 통해 정보를 넘길지 설정 할 수 있다.

never = 항상 정보 전달하지 않는다.

always = 항상 정보 전달한다.

on_param = 특정 파라미터 (?message=&errors=&trace=) 붙이면 전달

 

하지만 에러페이지는 사용자가 보는 페이지이고, 보안상의 위험이 있으므로 웬만하면 전달하지 않는것이 원칙이다.

 

 

<스프링 인터셉터와 예외처리>

포스팅 최상단의 그림을 보면, 처음 요청이 들어왔을때와 에러경로로 재요청될때, 스프링 인터셉터가 두번 실행된다.

이를 코드로 한번 확인해보자 그리고, 에러경로 요청시에는 인터셉터가 실행되지 않도록 설정해보자

다음과 같이 인터셉터를 정의했다. 인터셉터 정의 방식은 인터셉터 포스팅을 참고하자

이제 인터셉터를 등록할텐데, excludePathPattern 메서드의 인자에 주목하자

우선 이렇게 등록한 후 에러를 발생시켜 인터셉터를 실행시켜 보자

콘솔 결과

  INFO 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : REQUEST
  INFO 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : RESPONSE
 ERROR 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : afterCompletion error!!

 INFO 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : REQUEST 
 INFO 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : postHandle // 재요청시 에러 없으니 호출
 INFO 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : RESPONSE 

원 요청과 에러 재요청 두번 다 인터셉터가 실행된 것을 볼수 있다. postHandle 은 원요청에서 에러가 발생했으므로,

첫번째 인터셉터 요청에서는 실행되지 않았다. 이제 excludePathPattern 에 스프링 부트의 기본 에러경로를 추가하자

콘솔 결과

  INFO 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : REQUEST
  INFO 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : RESPONSE
 ERROR 19192 --- [nio-8080-exec-2] h.exeption.interceptor.LogInterceptor    : afterCompletion error!!

인터셉터가 에러 재요청시에 실행되지 않음을 알수 있다. 이렇게 실행되지 않는 경로를 설정하여, 인터셉터가

에러 재요청시에는 실행되지 않도록 설정할 수 있다.