Api 요청 결과를 제어하는 방법이 작성한 포스팅입니다.
[참고 자료]
- [Spring Boot] zkdlu/zkdlu/api-response-spring-boot-starter
[관련 포스트]
[활용 목적]
- Api 요청 결과에 대해 특정 포맷으로 변경하고 싶은 경우
[Dependencies]
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
...
}
구현
ServletResponseAdvice.java
더보기
작성 된 내용 중 더 좋은 방법으로 변경 및 제거할 수 있는 부분을 설명드리겠습니다.
1. 전역변수로 선언된 whitelist.
2. 구현부 중 instanceof 키워드를 통해 CommonResult Type 여부를 확인
whitelist 선언의 이유는 swagger에 대한 요청에 대해 beforeBodyWrite 함수가 동작하기 때문에
정상적인 Page 반환이 어렵습니다. 이를 해결하기 위해 해당 주소로 요청이 올 경우 제외하고자 선언하였습니다.
instanceof의 경우 이전 포스트의 ExceptionAdvice와 연관됩니다.
ExceptionAdvice를 통해 예외 처리를 성공하였을 경우에 대한 것도 beforeBodyWrite 함수가 동작합니다.
즉 ExceptionAdvice를 통해 예외 처리된 결과가 CommonResult 타입일 경우 다시 한 번 CommonResult로 감싸지게 됩니다.
물론 정상 동작에 대한 결괄르 CommonResult를 반환하는 경우 등도 해결하기 위해 instanceof 키워드를 사용하였습니다.
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@RestControllerAdvice
public class ServletResponseAdvice implements ResponseBodyAdvice<Object> {
private final List<PathPattern> whitelist = Arrays.asList(
new PathPatternParser().parse("/v*/api-docs"),
new PathPatternParser().parse("/swagger-resources/**"),
new PathPatternParser().parse("/swagger-ui.html"),
new PathPatternParser().parse("/webjars/**"),
new PathPatternParser().parse("/swagger/**"));
@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 (whitelist.stream().anyMatch(pathPattern -> pathPattern.matches(PathContainer.parsePath(request.getURI().getPath())))) return body;
if (body instanceof CommonResult) {
CommonResult commonResult = (CommonResult) body;
try {
HttpStatus status = HttpStatus.valueOf(commonResult.getStatus());
response.setStatusCode(status);
} catch (IllegalArgumentException e) {
response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
}
return commonResult;
}
int status = response instanceof ServletServerHttpResponse ? ((ServletServerHttpResponse) response).getServletResponse().getStatus() : 200;
return body != null ? SingleResult.success(body, status) : CommonResult.success(status);
}
}
[Git Repository]
'Backend > SpringBoot' 카테고리의 다른 글
[Mybatis] All Elements are null (0) | 2022.10.24 |
---|---|
[Spring Boot]Response Handling 하기-Flux (0) | 2022.07.10 |
[Spring Boot]Exception Handling 하기 (0) | 2022.07.09 |
[Spring Boot] Feign Client 로그 미동작 해결 (0) | 2022.06.10 |
[Spring Boot] Gradle을 사용하여 편하게 배포하자! (0) | 2021.12.12 |