一、初衷
最近所在的项目组,在项目后期,但是为了第三方接入方便,需要对API进行封装,形成第三方应用接入的sdk,此为背景。
二、因为发现springcloud fegin在http请求中比httpclinet resttemplate 这个组件调用更方便,同时结构清晰,所以果断使用fegin,在项目中使用了openfegin,在此记录一下。
三、具体实现
1.maven
在pom文件中共引入
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>12.1</version>
</dependency>
2.增加fegin的配置
此配置可以对fegin调用配置请求拦截器,以及是否重新发起请求的配置,当然也可以不配置有默认的配置
import feign.Feign;
import feign.Retryer;
import feign.querymap.BeanQueryMapEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfiguration {
@Bean
public Feign.Builder feignBuilder() {
return Feign.builder()
.queryMapEncoder(new BeanQueryMapEncoder())
.requestInterceptor(new FeignInterceptor())
.retryer(Retryer.NEVER_RETRY);
}
}
fegin的请求拦截器,可以实现公共的需求,比如接口验签,添加公共的请求头等等
@Component
public class FeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
HttpServletRequest httpServletRequest = ServletUtils.getRequest();
// 配置客户端IP
requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr(ServletUtils.getRequest()));
}
}
3.调用
其中url 为服务的实际地址,当然如果使用了服务中心,可以省略此配置
注意configuration 添加上自己定义的配置
@FeignClient(contextId = "remoteClientService" ,url = "${ywxt.url}", value = "remoteClientService", fallbackFactory =
RemoteClientService.class, configuration = FeignConfiguration.class)
public interface RemoteClientService {
@GetMapping("/demo")
ResultData<Object> demo(@PathVariable("bbb") String bbb,
@RequestHeader(SysGlobalConst.HTTP_HEADER_X_TENANT_ID) String source,
@RequestHeader(SysGlobalConst.HTTP_HEADER_X_AUTH_VALUE) String token);
}
配置fegin的服务降级
可以捕获异常信息并返回默认降级结果同时可以打印堆栈信息
@Component
public class RemoteClientFallbackFactory implements FallbackFactory<RemoteClientService> {
private static final Logger log = LoggerFactory.getLogger(RemoteClientFallbackFactory.class);
@Override
public RemoteClientService create(Throwable throwable) {
log.error(throwable.getMessage());
return new RemoteClientService() {
@Override
public ResultData<Object> demo(String username, String source, String token) {
return new ResultData(new RetCode(RetCode.BUSINESSERROR_CODE,RetCode.BUSINESSERROR_MSGID));
}
};
}
}
四.大功告成
end,在此记录一下,当然还能更多的配置,比如超时时间,重试次数等 更多配置,以后继续摸索。