专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

springboot项目中使用Feign调用远程服务

Spring Cloud Feign基于Netflix Feign实现,整合了Spring Cloud Riggon与Spring Cloud Hystrix,提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义方式。

创建feign 消费端项目
springcloud-feign-comsumer-demo

启动类添加@EnableFeignClients

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeignComsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignComsumerApplication.class, args);
    }
}

添加依赖包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
    <version>11.0</version>
</dependency>

添加配置项application.properties

feign.hystrix.enabled=true
feign.compression.request.enabled=true
feign.compression.request.mime-types=["text/xml","application/xml","application/json"]
feign.compression.request.min-request-size=2048
feign.compression.response.enabled=true
feign.client.config.default.logger-level=basic
feign.client.config.feign-provider-demo1.logger-level=full

创建feign配置类

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import okhttp3.ConnectionPool;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
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.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignConfig {

    /**
     * 设置 Eureka Server的访问的用户名和密码
     *
     * @return
     */
    /*@Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("admin","admin123");
    }*/

    @Bean
    public okhttp3.OkHttpClient okHttpClient(){
        return new okhttp3.OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .connectionPool(new ConnectionPool())
                .build();
    }

    @Bean
    public Feign.Builder feignBuilder() {
        return Feign.builder();
    }

    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    @Bean
    public Request.Options feignRequestOptions() {
        return new Request.Options(10000, 60000);
    }

    @Bean
    public Retryer feignRetry() {
        return new Retryer.Default();
    }

    @Bean
    public ResponseEntityDecoder feignDecoder() {
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(this.createFastJsonConverter());
        return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
    }

    @Bean
    public SpringEncoder feignEncoder(){
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(this.createFastJsonConverter());
        return new SpringEncoder(objectFactory);
    }

    private HttpMessageConverter createFastJsonConverter() {

        //创建fastJson消息转换器
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();

        //升级最新版本需加=============================================================
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_PROBLEM_JSON_UTF8);
        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        supportedMediaTypes.add(MediaType.IMAGE_GIF);
        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
        supportedMediaTypes.add(MediaType.IMAGE_PNG);
        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.TEXT_XML);

        fastConverter.setSupportedMediaTypes(supportedMediaTypes);

        //创建配置类
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //修改配置返回内容的过滤
        //WriteNullListAsEmpty  :List字段如果为null,输出为[],而非null
        //WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null
        //DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
        //WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null
        //WriteMapNullValue:是否输出值为null的字段,默认为false
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteMapNullValue
        );
        fastConverter.setFastJsonConfig(fastJsonConfig);
        return fastConverter;
    }

    //=======================================================

    /*
    @Bean
    public Decoder feignDecoder() {
        HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
        return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
    }
    @Bean
    public Encoder feignEncoder(){
        HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
        return new SpringEncoder(objectFactory);
    }
    */

    private ObjectMapper customObjectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        //Customize as much as you want
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        return objectMapper;
    }

}

创建Feign调用远程Api

@FeignClient(name = "SERVICE-PROVIDER-API-DEMO1",
        url = "http://localhost:8077",
        configuration = FeignConfig.class,
        fallback = DemoFeignApiFallback.class)
public interface DemoFeignApi {

    @Headers(value={"Content-type:application/json;charset=UTF-8"})
    @RequestLine(value = "POST /feign/provider/user/save")
    @ResponseBody
    String userSave(@RequestBody User user);

    @Headers(value={"Content-type:application/json;charset=UTF-8"})
    @RequestLine(value = "GET /feign/provider/user/{id}")
    @ResponseBody
    String getUserById(@Param("id") Integer id);
}

public class DemoFeignApiFallback implements DemoFeignApi {

    @Override
    public String userSave(User user) {
        return null;
    }

    @Override
    public String getUserById(Integer id) {
        return null;
    }
}

创建unit test测试类

@SpringBootTest(classes =FeignComsumerApplication.class)
public class FeignDemoApplicationTests {

    @Autowired
    DemoFeignApi feignApi;

    @Test
    public void userSave() {
        System.out.println(">>>>>>>>>>userSave");
        String resp = feignApi.userSave(new User(1, "qwer", "12456", new Date()));
        System.out.println(">>>>>>>>>>resp: {}" + resp);
    }

    @Test
    public void getUserById() {
        System.out.println(">>>>>>>>>>getUserById");
        String resp = feignApi.getUserById(1);
        System.out.println(">>>>>>>>>>resp: {}" + resp);
    }
}

测试结果

启动服务提供端后,执行测试,结果如下

118_1.png

源码示例:https://gitee.com/lion123/springcloud-rcp-demo/tree/master/springcloud-feign-comsumer-demo

文章永久链接:https://tech.souyunku.com/24901

未经允许不得转载:搜云库技术团队 » springboot项目中使用Feign调用远程服务

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们