티스토리 뷰
Spring Boot WebFlux - Thymeleaf 환경에서 에러 핸들링 하는 방법을 소개한다.
아래는 참고한 가이드
https://www.baeldung.com/spring-webflux-errors
Handling Errors in Spring WebFlux | Baeldung
Have a look at different methods to gracefully handle errors in Spring Webflux.
www.baeldung.com
하지만 위 예제는 error status에 따른 json return만 구현되어있기 때문에,
우리가 통상적으로 생각하는 404/500에 대한 error 처리를 하기 위해서는 추가적인 작업이 필요하다.
완성된 코드는 아래와 같다.
@Component
@Order(-2)
public class ExceptionHandlerConfiguration extends AbstractErrorWebExceptionHandler {
public ExceptionHandlerConfiguration(ErrorAttributes errorAttributes,
ResourceProperties resourceProperties,
ApplicationContext applicationContext,
ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer configurer) {
super(errorAttributes, resourceProperties, applicationContext);
this.setMessageWriters(configurer.getWriters());
this.setViewResolvers(viewResolversProvider.getIfAvailable());
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
Map<String, Object> errorPropertiesMap = getErrorAttributes(request, false);
/*int status = (int) errorPropertiesMap.get("status");
// status에 따른 분기처리 (html view)
if(status >= 500){
return ok().render("error/500");
}else{
return ok().render("error/404");
}*/
// json return
return ServerResponse.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(errorPropertiesMap));
}
}
@Component
@Order(-2)
public class ExceptionHandlerConfiguration extends AbstractErrorWebExceptionHandler {
...
}
configure의 순서를 정렬한다.
Spring Boot에서 DefaultErrorWebExceptionHandler가 -1, ResponseStatusExceptionHandler가 0으로 설정되어 있기 때문에
-2로 내려야 위 요소들보다 먼저 배치되게 된다.
public ExceptionHandlerConfiguration(ErrorAttributes errorAttributes,
ResourceProperties resourceProperties,
ApplicationContext applicationContext,
ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer configurer) {
super(errorAttributes, resourceProperties, applicationContext);
this.setMessageWriters(configurer.getWriters());
this.setViewResolvers(viewResolversProvider.getIfAvailable());
}
생성자에서 AbstractErrorWebExceptionHandler의 생성자를 호출하고,
그 아래에 MessageWriter와 ViewResolver를 정의한다. (이게 가장 핵심)
인자로 List<ViewResolver>를 받아오는데, 이때 사용중인 템플릿 엔진이 Thymeleaf라면 ThymeleafResolver가
다른 템플릿 엔진이라면 다른 리졸버가 들어올것이다.
해당 부분을 정의하지 않으면 DefaultRenderingResponseBuilder.writeToInternal에서 ViewResolver를 찾지 못하기 때문에
500에러가 발생하게 된다.
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
라우팅 부분이다.
모든 요청에 대해 받되, ErrorAttributes 인자가 있을 경우 renderErrorResponse 함수가 실행되게 된다.
private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
Map<String, Object> errorPropertiesMap = getErrorAttributes(request, false);
/*int status = (int) errorPropertiesMap.get("status");
// status에 따른 분기처리 (html view)
if(status >= 500){
return ok().render("error/500");
}else{
return ok().render("error/404");
}*/
// json return
return ServerResponse.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(errorPropertiesMap));
}
해당 부분에서 실질적인 에러 처리를 진행한다.
주석처리 된 부분은 템플릿 엔진을 사용중일 경우 해당 html view가 노출되도록 return하는 부분이며,
최하단의 return은 JSON형식으로 에러정보가 return된다.
(필자의 경우에는 Thymeleaf를 사용중이기 때문에, error/404를 호출시 실제로는 reousrces/templates/error/404를 바라보게 된다.)
에러코드에 대한 정의와 어떤 템플릿을 보여줄것인지, 어떤 요청이 들어왔을때 어떻게 리턴해줄것인지는
각 사용자가 입맛에 맞게끔 구현 해 사용하면 될것이다.
'개발 이야기 > SPRING' 카테고리의 다른 글
- Total
- Today
- Yesterday
- JPA
- Thymeleaf
- hibernate
- intellij
- SI
- Spring Security
- Java
- Spring Cache
- 친환경차
- spring-jpa
- spring webflux
- 저공해자동차 스티커
- Spring
- 스프링
- 취업
- Spring Boot
- Weblogic
- CSRF
- 국비교육
- Util
- memcached
- query-dsl
- 이직
- 저공해자동차
- WebFlux
- multipart
- spring-data-jpa
- SpringDataJPA
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |