乐趣区

关于java:SpringBoot使用Feign调用其他服务接口

应用 SpringCloud 的 Feign 组件可能为服务间的调用节俭编码工夫并进步开发效率,当服务自身不简单时能够独自将该组件拿出应用。

引入依赖

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-openfeign</artifactId>
 <version>2.0.4.RELEASE</version>
</dependency>

引入 SpringBoot 打包的 Feign 依赖,须要留神的是 Feign 的版本与 SpringBoot 版本的对应关系,老版本的 Feign 并不叫 openfeign。因为我是用的 SpringBoot 版本是 2.0x,所以 openfeign 应用了 2.0x 版本,若应用诸如 2.1x 或其余高版本的 openfeign,在我的项目启动时会报“形象办法谬误”这类的异样。

编写接口作为服务调用入口

import com.bhz.demo.client.domain.req.ProductReceiveReq;
import com.bhz.demo.client.domain.resp.MemberPointBaseResp;
import com.bhz.demo.client.domain.resp.UserPointResp;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @Author guomz 
 * @create 2021/3/15 14:50 
 */
@FeignClient(url = "www.123.com", name = "demoClient")
public interface DemoClient {@RequestMapping(value = "/demo/user/{uuid}/{name}", method = RequestMethod.GET)
    DemoBaseResp<DemoUserResp> getUser(@PathVariable("uuid") String uuid, @PathVariable("name") String name);
    
    @RequestMapping(value = "/demo/buy", method = RequestMethod.POST)
    DemoBaseResp buyProduct(DemoBuyReq req);
}

Feign 的服务调用编写相似 mybatis 的 dao 接口,接口上方须要标注 @FeignClient 注解,该注解有 urlnamevalue 三个重要参数。其中 namevalue等效,必须填写一个。在微服务环境下 namevalue填写用于被注册核心发现的服务名,例如调用的用户服务叫 userService 则此处填写 userService,此使 url 能够不填写,因为曾经指定了调用方。url则是间接指定服务的全门路,若同时填写 urlname,则以 url 为准,name便被当作以后客户端的名称。
下面的示例并不属于简单的微服务环境,所以采纳间接指定 url 来调用其余服务。
办法定义上与 controller 基本一致,须要留神 post 办法不能传递多个参数,须要用 map 或对象进行封装。

调用服务

@Service
@Slf4j
public class DemoService {
 @Autowired
 private DemoClient demoClient;
 public void getUser(Long id){demoClient.getUser("123", "abc");
 }
}

在须要调用其余服务的模块中引入之前定义的接口即可。

对于调用 https 接口

调用 https 接口时会进行证书校验,若没有证书则会抛出 No subject alternative names present 异样,能够应用以下代码来绕过证书校验:

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-ribbon -->
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
 <version>2.0.4.RELEASE</version>
</dependency>

首先须要引入 Ribbon 依赖,在绕过证书的代码中存在一些须要被注入的类属于 Ribbon。Ribbon 的引入同样须要留神版本问题。

import feign.Client;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
/**feign client 配置
 * @Author guomz
 * @create 2021/3/16 9:52
 */
 @Configuration
public class FeignConfiguration {

/**
 * 调用 https 接口时绕过 ssl 证书验证
 * @param cachingFactory
 * @param clientFactory
 * @return
 * @throws NoSuchAlgorithmException
 * @throws KeyManagementException
 */
 @Bean
 @ConditionalOnMissingBean public Client feignClient(@Qualifier("cachingLBClientFactory") CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) throws NoSuchAlgorithmException, KeyManagementException {SSLContext ctx = SSLContext.getInstance("TLSv1.2");
        X509TrustManager tm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) { }
                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) { }
                @Override
                public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];
                 }
        };
        ctx.init(null, new TrustManager[]{tm}, null);
        return new LoadBalancerFeignClient(new Client.Default(ctx.getSocketFactory(), new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession sslSession) {return true;}
                }),
        cachingFactory, clientFactory);
     }
}

之后是 Feign 的配置类,用来绕过 https 证书校验。

退出移动版