본문 바로가기

Backend/SpringBoot

[Spring Boot]Response Handling 하기-MVC

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]

 

 

GitHub - PCloud63514/SpringSkilsExample: 스프링 부트를 사용하며 적용했던 기술들을 정리한 문서

스프링 부트를 사용하며 적용했던 기술들을 정리한 문서. Contribute to PCloud63514/SpringSkilsExample development by creating an account on GitHub.

github.com