Handler(Controller)에서 반환된 @ResponseBody 또는 HTTP 메시지 변환 결과를 가로채어 추가적인 처리를 할 수 있도록 제공되는 인터페이스
public interface ResponseBodyAdvice<T> {
boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);
@Nullable
T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response);
}
@RestControllerAdvice
public class CustomResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// 모든 컨트롤러에 적용하거나 특정 조건을 설정 가능
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
// 공통 응답 포맷 적용
if (body instanceof ApiResponse) {
return body; // 이미 포맷이 적용된 경우 그대로 반환
}
return new ApiResponse("success", body);
}
}
// 공통 응답 구조를 위한 DTO
public class ApiResponse {
private String status;
private Object data;
public ApiResponse(String status, Object data) {
this.status = status;
this.data = data;
}
}
@RestControllerAdvice
public class SensitiveDataMaskingAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// 특정 데이터 타입에만 적용
return returnType.getParameterType().equals(UserDto.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof UserDto) {
UserDto user = (UserDto) body;
user.setPassword(null); // 비밀번호 제거
return user;
}
return body;
}
}
@Slf4j
@RequiredArgsConstructor
@RestControllerAdvice
public class CustomResponseBodyAdvice implements ResponseBodyAdvice{
private final ObjectMapper objectMapper;
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return returnType.getParameterType().equals(ResponseVo.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
this.setDefaultValue(body);
this.logging(body, selectedContentType);
return body;
}
private void setDefaultValue(ResponseVo<?> responseVo) {
ResponseVo<?> responseVo = (ResponseVo<?>) body;
responseVo.setTimestamp(LocalDateTime.now());
}
private void logging(Object body, MediaType selectedContentType) {
try {
// JSON 변환 가능한 경우만 처리
if (body != null && MediaType.APPLICATION_JSON.includes(selectedContentType)) {
String json = objectMapper.writeValueAsString(body);
log.info("Response Body (JSON): {}", json);
}
} catch (Exception e) {
log.error("Error while converting response body to JSON", e);
}
}
}
RequestBodyAdvice에 대한 내용은 아래글을 참고하기 바란다.
RequestBodyAdvice 인터페이스 파해치기 (23) | 2024.12.30 |
---|---|
Jackson - ObjectMapper 사용법 (readValue, writeValue, JsonNode, ObjectNode) (42) | 2024.12.26 |
Jackson - ObjectMapper Custom 설정 (0) | 2024.12.24 |
ImmutableList에 대한 고찰 (1) | 2024.10.13 |
SpringBoot CSV Read / Write (opencsv) (8) | 2024.09.12 |
댓글 영역