wnjustdoit
7/8/2020 - 5:39 AM

Customized RequestResponseBodyMethodProcessor

In Spring Cloud with Feign Client, fix @RequestBody of Server Provider cannot be inherited problem.

package com.caiya.test.spring.cloud.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.lang.reflect.Method;
import java.util.List;

/**
 * WebMvcConfiguration.
 *
 * @author wangnan
 * @since 1.0.0, 2020/7/8
 **/
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    private List<HttpMessageConverter<?>> converters;

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        this.converters = converters;
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(0, new RequestResponseBodyMethodProcessor(this.converters) {
            @Override
            public boolean supportsParameter(MethodParameter parameter) {
                if (!parameter.hasParameterAnnotation(RequestBody.class)) {
                    for (Class<?> inter : parameter.getDeclaringClass().getInterfaces()) {
                        Method method = null;
                        try {
                            method = inter.getMethod(parameter.getMethod().getName(), parameter.getMethod().getParameterTypes());
                        } catch (NoSuchMethodException e) {
                            continue;
                        }
                        MethodParameter interParameter = new MethodParameter(method, parameter.getParameterIndex());
                        // When one of the interfaces has @RequestBody annotation, return true
                        if (interParameter.hasParameterAnnotation(RequestBody.class)) {
                            return true;
                        }
                    }
                }

                return super.supportsParameter(parameter);
            }
        });
    }
}