好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

@FeignClient 实现简便http请求封装方式

@FeignClient实现http请求封装

我们一般在代码中调用http请求时,都是封装了http调用类,底层自己定义请求头,在写的时候,也是需要对返回的值进行json解析,很不方便。

name :name属性会作为微服务的名称,用于服务发现 url :host的意思,不用加http://前缀 decode404 :当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException

使用流程

(1)创建接口类(FeignApi),来统一规范需要调用的第三方接口

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@FeignClient (name = "aaa" , url = "localhost:8080" , decode404 = true )

public interface FeignApi {

    /**

      * http请求

      */

    @PostMapping ( "/api/xxxx/baiduaaa" )

    ResponseResult<ResponseVo> getSomeMoneyForYourSelfAAA( @RequestBody AAAParam param);

    

    /**

      * 模仿上面写的Get方式请求

      */

    @GetMapping ( "/api/xxxx/baidubbb" )

    ResponseResult<ResponseVo> getSomeMoneyForYourSelfBBB( @RequestBody AAAParam param);

}

(2)在启动类加上注解,会去扫包注册Bean

?

1

@EnableFeignClients (basePackages = { "com.aaa" })

(3)业务代码调用处:

?

1

ResponseResult<ResponseVo> response = pmsFeignApi.getSomeMoneyForYourSelfAAA(param);

将http请求封装为FeignClient

1.配置拦截器

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

import java.io.IOException;

import java.io.InterruptedIOException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import okhttp3.Interceptor;

import okhttp3.Request;

import okhttp3.Response;

public class OkHttpRetryInterceptor implements Interceptor {undefined

    private static final Logger LOGGER = LoggerFactory.getLogger(OkHttpRetryInterceptor. class );

    /**

      * 最大重试次数

      */

    private int                 executionCount;

    /**

      * 重试的间隔

      */

    private long                 retryInterval;

    OkHttpRetryInterceptor(Builder builder) {undefined

        this .executionCount = builder.executionCount;

        this .retryInterval = builder.retryInterval;

    }

    @Override

    public Response intercept(Chain chain) throws IOException {undefined

        Request request = chain.request();

        Response response = doRequest(chain, request);

        int retryNum = 0 ;

        while ((response == null || !response.isSuccessful()) && retryNum <= executionCount) {undefined

            LOGGER.info( "intercept Request is not successful - {}" , retryNum);

            final long nextInterval = getRetryInterval();

            try {undefined

                LOGGER.info( "Wait for {}" , nextInterval);

                Thread.sleep(nextInterval);

            } catch ( final InterruptedException e) {undefined

                Thread.currentThread().interrupt();

                throw new InterruptedIOException();

            }

            retryNum++;

            // retry the request

            response = doRequest(chain, request);

        }

        return response;

    }

    private Response doRequest(Chain chain, Request request) {undefined

        Response response = null ;

        try {undefined

            response = chain.proceed(request);

        } catch (Exception e) {undefined

        }

        return response;

    }

    /**

      * retry间隔时间

      */

    public long getRetryInterval() {undefined

        return this .retryInterval;

    }

    public static final class Builder {undefined

        private int   executionCount;

        private long retryInterval;

        public Builder() {undefined

            executionCount = 3 ;

            retryInterval = 1000 ;

        }

        public Builder executionCount( int executionCount) {undefined

            this .executionCount = executionCount;

            return this ;

        }

        public Builder retryInterval( long retryInterval) {undefined

            this .retryInterval = retryInterval;

            return this ;

        }

        public OkHttpRetryInterceptor build() {undefined

            return new OkHttpRetryInterceptor( this );

        }

    }

}

2.注入feignClient bean

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.autoconfigure.AutoConfigureBefore;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;

import org.springframework.cloud.netflix.feign.ribbon.CachingSpringLoadBalancerFactory;

import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient;

import org.springframework.cloud.netflix.ribbon.SpringClientFactory;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import feign.Client;

import feign.Feign;

import feign.ribbon.RibbonClient;

import okhttp3.ConnectionPool;

import okhttp3.OkHttpClient;

@Configuration

@ConditionalOnMissingBean ({ OkHttpClient. class , Client. class })

@ConditionalOnClass (Feign. class )

@AutoConfigureBefore (FeignAutoConfiguration. class )

public class FeignClientConfig {undefined

    @Value ( "${feign.invoke.http.connectTimeoutMillis:3000}" )

    private int connectTimeoutMillis;

    @Value ( "${feign.invoke.http.readTimeoutMillis:10000}" )

    private int readTimeoutMillis;

    @Value ( "${feign.invoke.http.retryExecutionCount:3}" )

    private int retryExecutionCount;

    @Value ( "${feign.invoke.http.retryInterval:1000}" )

    private int retryInterval;

    public FeignClientConfig() {undefined

    }

    @Bean

    @ConditionalOnMissingBean ({ OkHttpClient. class })

    public OkHttpClient okHttpClient() {undefined

        OkHttpRetryInterceptor okHttpRetryInterceptor = new OkHttpRetryInterceptor.Builder().executionCount(retryExecutionCount)

                                                                                            .retryInterval(retryInterval)

                                                                                            .build();

        return new OkHttpClient.Builder().retryOnConnectionFailure( true )

                                          .addInterceptor(okHttpRetryInterceptor)

                                          .connectionPool( new ConnectionPool())

                                          .connectTimeout(connectTimeoutMillis, TimeUnit.MILLISECONDS)

                                          .readTimeout(readTimeoutMillis, TimeUnit.MILLISECONDS)

                                          .build();

    }

    @Bean

    @ConditionalOnMissingBean ({ Client. class })

    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {undefined

        if (cachingFactory == null ) {undefined

            RibbonClient.Builder builder = RibbonClient.builder();

            builder.delegate( new feign.okhttp.OkHttpClient( this .okHttpClient()));

            return builder.build();

        } else {undefined

            return new LoadBalancerFeignClient( new feign.okhttp.OkHttpClient( this .okHttpClient()), cachingFactory,

                                                clientFactory);

        }

    }

}

3.配置pom引用

?

1

2

3

4

5

  < dependency >

  < groupId >io.github.openfeign</ groupId >

  < artifactId >feign-ribbon</ artifactId >

  < version >9.0.0</ version >

  </ dependency >

4.写feignClient

?

1

2

3

4

5

6

@FeignClient (name = "xxxApi" , url = "${xxx.url}" )

public interface xxxClient {

      @RequestMapping (method = RequestMethod.POST)

      public String createLink( @RequestHeader (name = "accessKey" , defaultValue = "xx" ) String accessKey,

          @RequestHeader (name = "accessSecret" ) String accessSecret, @RequestBody String linkConfig);

}

5.写熔断器

?

1

2

3

4

5

6

7

8

9

10

    @Autowired

    private xxxClient xxClient;

    @HystrixCommand (commandKey = "xxxLink" , fallbackMethod = "xxxError" , commandProperties = { @HystrixProperty (name = "requestCache.enabled" , value = "true" ),

                                                                                                                            @HystrixProperty (name = "execution.isolation.thread.timeoutInMilliseconds" , value = "5000" ) })

    public String xxLink(String accessKey, String accessSecret, String linkConfig) {

        LOG.info( "[xxLink]  LinkConfig is {}" , linkConfig);

        String resp = xxxClient.createLink(accessKey, accessSecret, linkConfig);

        LOG.info( "[xxxLink] response : {}" , resp);

        return resp;

    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/qq_40555976/article/details/123005668

查看更多关于@FeignClient 实现简便http请求封装方式的详细内容...

  阅读:17次