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

网友投稿 382 2022-08-22


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

目录@FeignClient实现http请求封装使用流程将http请求封装为FeignClient1.配置拦截器2.注入feignClientbean3.配置pom引用4.写feignClient5.写熔断器

@FeignClient实现http请求封装

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

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

使用流程

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

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

public interface FeignApi {

/**

* http请求

*/

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

ResponseResult getSomeMoneyForYourSelfAAA(@RequestBody AAAParam param);

/**

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

*/

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

ResponseResult getSomeMoneyForYourSelfBBB(@RequestBody AAAParam param);

}

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

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

(3)业务代码调用处:

ResponseResult response = pmsFeignApi.getSomeMoneyForYourSelfAAA(param);

将http请求封装为FeignClient

1.配置拦截器

import java.io.IOException;

import java.io.InterruptedIOException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import okhttp3.http://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

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.HeMTbBuilder().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引用

io.github.openfeign

feign-ribbon

9.0.0

4.写feignClient

@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.写熔断器

@Autowired

private xxxClient xxClient;

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

http:// @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;

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解析Spring中@Controller@Service等线程安全问题
下一篇:面试Spring中的bean线程是否安全及原因
相关文章

 发表评论

暂时没有评论,来抢沙发吧~