본문 바로가기

Backend/SpringBoot

[Spring Boot]Response Handling 하기-Flux

[관련 포스트]

[활용 목적]

  • Flux 환경에서 Api 요청 결과에 대해 특정 포맷으로 변경하고 싶은 경우

[Dependencies]

dependencies {
	...
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    // 별도의 모듈로 만들고 stater-webflux까지 필요하진 않는 경우
	// implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
    // implementation 'org.springframework:spring-webflux:5.0.1.RELEASE'
    compileOnly 'org.projectlombok:lombok'
    ...
}

구현

ReactiveResponseAdvice.java

@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class ReactiveResponseAdvice extends ResponseBodyResultHandler {
    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/**"));
    private static MethodParameter param;

    static {
        try {
            param = new MethodParameter(ReactiveResponseAdvice.class
                    .getDeclaredMethod("methodForParams"), -1);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public ReactiveResponseAdvice(List<HttpMessageWriter<?>> writers, RequestedContentTypeResolver resolver) {
        super(writers, resolver);
    }

    @Override
    public boolean supports(HandlerResult result) {
        return true;
    }

    private static Object methodForParams() {
        return null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
        if (whitelist.stream().anyMatch(pathPattern -> pathPattern.matches(PathContainer.parsePath(exchange.getRequest().getURI().getPath())))
                || result.getReturnValue() instanceof CommonResult) {
            return writeBody(result.getReturnValue(), param, exchange);
        }

        Object obj = result.getReturnValue();

        if (result.getReturnValue() instanceof Mono) {
            obj = ((Mono<?>) result.getReturnValue()).block();
            if (obj instanceof CommonResult) {
                return writeBody(obj, param, exchange);
            }
        }
        boolean isNotEmptyBody = obj != null;
        CommonResult body = isNotEmptyBody ? SingleResult.success(obj) : CommonResult.success();
        return writeBody(body, param, exchange);
    }
}

ReactiveConfig.java

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class ReactiveConfig {
    ...
    @Bean
     public ResponseBodyResultHandler responseBodyResultHandler(
             ServerCodecConfigurer serverCodecConfigurer,
             RequestedContentTypeResolver contentTypeResolver) {
         return new ReactiveResponseAdvice(serverCodecConfigurer.getWriters(),
                 contentTypeResolver);
     }
    ...
}

[Git Repository]

 

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

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

github.com