(一)Feign之支持文件上传和使用对象作为参数接收

一、需求描述
1、需要支持文件上传。
2、使用实体类的对象作为参数传递。
3、POST请求方式为Form表单提交。Content-Type: application/x-www-form-urlencoded。

二、术语解释
1、Logger.Level:日志级别

2、Retryer:重试机制

3、ErrorDecoder:错误解码器

4、Request.Options:
connectTimeoutMillis;// connectTimeout配置项
readTimeoutMillis;// readTimeout配置项

5、RequestInterceptor:请求拦截器

6、Contract::处理Feign接口注解,Spring Cloud Feign 使用SpringMvcContract 实现,处理Spring mvc 注解,也就是我们为什么可以用Spring mvc 注解的原因。

7、Client:Http客户端接口,默认是Client.Default,但是我们是不使用它的默认实现,Spring Cloud Feign为我们提供了okhttp3和ApacheHttpClient两种实现方式,只需使用maven引入以下两个中的一个依赖即可,版本自由选择。

8、Encoder:编码器,将一个对象转换成http请求体中, Spring Cloud Feign 使用 SpringEncoder

9、Decoder:解码器, 将一个http响应转换成一个对象,Spring Cloud Feign 使用 ResponseEntityDecoder

10、FeignLoggerFactory:日志工厂

11、Feign.Builder:Feign接口构建类,覆盖默认Feign.Builder,比如:HystrixFeign.Builder

12、FeignContext:管理了所有的java config 配置

三、具体实现

import com.fasterxml.jackson.core.JsonParser;
import feign.Contract;
import feign.Logger;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.form.FormEncoder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.annotation.PathVariableParameterProcessor;
import org.springframework.cloud.openfeign.annotation.RequestHeaderParameterProcessor;
import org.springframework.cloud.openfeign.annotation.RequestParamParameterProcessor;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.util.ArrayList;
import java.util.List;


@Configuration
public class FeignServiceConfiguration {

    HttpMessageConverter mappingJackson2HttpMessageConverter = new ContentTypeFixedJackson2HttpMessageConverter();

    private static class ContentTypeFixedJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
        public ContentTypeFixedJackson2HttpMessageConverter() {
            super(Jackson2ObjectMapperBuilder.json()
                            .featuresToEnable(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS,
                                    JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER)
                            .build(),
                    MediaType.TEXT_HTML,
                    MediaType.APPLICATION_JSON_UTF8,
                    new MediaType("application", "*+json"));
        }
    }

    HttpMessageConverters messageConverters = new HttpMessageConverters(mappingJackson2HttpMessageConverter);

    ObjectFactory messageConvertersFactory = new ObjectFactory() {
        @Override
        public HttpMessageConverters getObject() throws BeansException {
            return messageConverters;
        }
    };

    @Bean
    public Decoder feignDecoder() {
        return new ResponseEntityDecoder(new SpringDecoder(this.messageConvertersFactory));
    }

    @Bean
    public Encoder feignEncoder() {
        return new FormEncoder(new SpringEncoder(messageConvertersFactory));
    }

    /**
     * 开启Feign的日志
     *
     * @return
     */
    @Bean
    public Logger.Level logger() {
        return Logger.Level.FULL;
    }
}

四、测试结果

...[TestFeignClient#post] ---> POST http://www.baidu.com/test HTTP/1.1
...[TestFeignClient#post] Accept: application/json;charset=UTF-8
...[TestFeignClient#post] Content-Type: application/x-www-form-urlencoded; charset=UTF-8
...[TestFeignClient#post] Content-Length: 30
...[TestFeignClient#post] 
...[TestFeignClient#post] password=123456&username=admin
...[TestFeignClient#post] ---> END HTTP (30-byte body)

你可能感兴趣的:((一)Feign之支持文件上传和使用对象作为参数接收)