기본 응답
Gateway에서 예외가 발생하면 기본으로 응답되는 포맷은 다음과 같음
{
"timestamp": "2024-02-14T08:43:24.955+00:00",
"path": "/first-service/hello-post",
"status": 401,
"error": "Unauthorized",
"requestId": "3cafcce1"
}
응답을 커스텀하거나 예외 발생 시 특별한 처리를 하려고 하는 경우, Gateway 필터를 구현하는 것처럼 ExceptionHandler를 구현할 수 있음
GatewayResponseVO
Gateway에서 응답을 커스텀하기 위해 먼저 VO를 정의
@Data
public class GatewayResponseVO {
private int status;
private String message;
private Object data;
private boolean success;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime timestamp;
/**
* Constructor for success response
* @param data
*/
public GatewayResponseVO(Object data) {
this.status = 200;
this.message = "Success";
this.data = data;
this.success = true;
this.timestamp = LocalDateTime.now();
}
/**
* Constructor for error response
* @param status
* @param message
*/
public GatewayResponseVO(int status, String message) {
this.status = status;
this.message = message;
this.success = false;
this.timestamp = LocalDateTime.now();
}
}
CustomGlobalExceptionHandler 구현
예외가 발생하면 GatewayResponseVO를 정의하여 응답하는 ExceptionHandler
@Order(-2) // 우선 순위 부여
@Component // 빈으로 등록하여 ExceptionHandler 작동하도록 함
public class CustomGlobalExceptionHandler extends AbstractErrorWebExceptionHandler {
public CustomGlobalExceptionHandler(ErrorAttributes errorAttributes, WebProperties webProperties, ApplicationContext applicationContext, ServerCodecConfigurer configurer) {
super(errorAttributes, webProperties.getResources(), applicationContext);
this.setMessageWriters(configurer.getWriters());
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
ErrorAttributeOptions options = ErrorAttributeOptions.of(ErrorAttributeOptions.Include.MESSAGE);
// errorPropertiesMap을 로그 찍어보면 기본 응답의 형태로 생김
Map<String, Object> errorPropertiesMap = getErrorAttributes(request, options);
// status 있으면 사용, 없으면 500 에러로
Object status = errorPropertiesMap.getOrDefault("status", 500);
GatewayResponseVO response = new GatewayResponseVO((Integer) status, (String) errorPropertiesMap.get("message"));
return ServerResponse
.status((Integer) status)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(response));
}
}
errorPropertiesMap으로 부터 정보를 가져와 GatewayResponseVO를 정의한 후 ServerResponse의 body로 전달
{
"status": 401,
"message": "Unauthorized",
"data": null,
"success": false,
"timestamp": "2024-02-14T18:03:58"
}
ExceptionHandler를 적용한 후 예외를 발생시키면 위와 같이 응답이 바뀐 것을 확인할 수 있음
'Spring' 카테고리의 다른 글
Spring Cloud Gateway Filter에서 응답 보내기 (0) | 2024.02.08 |
---|---|
Spring Boot spring-security-oauth2-jose 사용해 JWKS URI로 JWT 검증하기 (0) | 2024.02.08 |
Spring Cloud Gateway 구현 정리 (1) | 2024.02.06 |
Java Spring JWT 생성 및 검증 로직 구현 (0) | 2024.01.11 |
Java Spring에서 JWKS(JSON Web Key Set) API 구현 (1) | 2024.01.11 |
댓글