All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ileler.swjp.JsonParamConfigForWebFlux Maven / Gradle / Ivy

The newest version!
package org.ileler.swjp;

import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.ui.Model;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver;
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoSink;

import java.util.HashMap;
import java.util.Map;

/**
 * Author: [email protected]
 */
public class JsonParamConfigForWebFlux implements WebFluxConfigurer {

    public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
        configurer.addCustomResolver(new HandlerMethodArgumentResolverForFlux());
    }

    class HandlerMethodArgumentResolverForFlux extends AbstractMessageReaderArgumentResolver {

        private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";

        public HandlerMethodArgumentResolverForFlux() {
            super(ServerCodecConfigurer.create().getReaders(), ReactiveAdapterRegistry.getSharedInstance());
        }

        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            return JsonParamResolver.supportsParameter(parameter);
        }

        public Mono resolveArgument(MethodParameter methodParameter, BindingContext bindingContext, ServerWebExchange serverWebExchange) {
            JsonParamBean jsonParamBean = JsonParamResolver.resolveArgument(methodParameter);
            Model model = bindingContext.getModel();
            return Mono.defer(() -> {
                if (model.asMap().containsKey(JSONBODYATTRIBUTE)) {
                    return Mono.create(
                            (callback -> ((Map>) model.asMap().get(JSONBODYATTRIBUTE)).put(jsonParamBean, callback))
                    );
                }
                model.addAttribute(JSONBODYATTRIBUTE, new HashMap>());
                return readBody(methodParameter, false, bindingContext, serverWebExchange).map(json -> {
                    ((Map>) model.asMap().get(JSONBODYATTRIBUTE)).forEach(
                            (JsonParamBean bean, MonoSink callback) -> callback.success(bean.getValue((String) json))
                    );
                    return jsonParamBean.getValue((String) json);
                });
            });
        }

    }


}