07、第一个Feign程序

216 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

07、第一个Feign程序

1、使用CXF调用REST 服务

  CXF 是目前一个较为流行的 Web Service 框架,是 Apache 个开源项目。使用 CXF 可以发布和调用使用各种协议的服务,包括 SOAP 协议、 XML/HTTP 等。当前 CXF 已经 对阳ST 风格的 Web Service 提供支持,可以发布或调用阻ST 风格的 Web Service 。由于 CXF 可以与 Spring 进行整合使用并且配置简单,因此得到许多开发者的青睐,而笔者以往 所在公司的大部分项目,均使用 CXF 来发布和调用 Web Service 。本章所使用的 CXF 版本 3.1.10 ,在 Maven 中加入以下依赖:

<!--cxf的依赖start-->
 <dependency>
     <groupId>org.apache.cxf</groupId>
     <artifactId>cxf-core</artifactId>
     <version>3.1.10</version>
 </dependency>
 <dependency>
     <groupId>org.apache.cxf</groupId>
     <artifactId>cxf-rt-rs-client</artifactId>
     <version>3.1.10</version>
 </dependency>
 <!--cxf的依赖end-->

编写代码请求/person/ {personld }服务

/**
 * 使用CXF调用REST服务
 * 客户端中使用了 WebClient 类发送请求,获取响应后读取输入流,获取服务返回的 JSON
字符串。
 */
public static void main(String[] args) throws Exception {
    // 创建WebClient
    WebClient client = WebClient.create("http://localhost:8888/person/1");
    // 获取响应
    Response response = client.get();
    // 获取响应内容
    InputStream ent = (InputStream) response.getEntity();
    String content = IOUtils.readStringFromStream(ent);
    // 输出字符串
    System.out.println(content);
}

##2、使用Restlet调用REST 服务 Restlet 是一个轻量级的 REST 框架,使用它可以发布和调用 REST 风格的 Web Service MAVEN依赖如下:

<!--restlet的依赖start-->
<dependency>
    <groupId>org.restlet.jee</groupId>
    <artifactId>org.restlet</artifactId>
    <version>2.3.10</version>
</dependency>
<dependency>
    <groupId>org.restlet.jee</groupId>
    <artifactId>org.restlet.ext.jackson</artifactId>
    <version>2.3.10</version>
</dependency>

<!--restlet的依赖end-->

阿里云仓库里没有restlet Jar包
 <repository>
     <id>maven-restlet</id>
     <name>Restlet repository</name>
     <url>http://maven.restlet.org</url>
 </repository>
客户端代码如下:
public class RestletClient {

	public static void main(String[] args) throws Exception {
		ClientResource client = new ClientResource(
				"http://localhost:8888/person/1");
		// 调用get方法,服务器发布的是GET
		Representation response = client.get(MediaType.APPLICATION_JSON);
		// 创建JacksonRepresentation实例,将响应转换为Map
		JacksonRepresentation jr = new JacksonRepresentation(response,HashMap.class);
		// 获取转换后的Map对象
		Map result = (HashMap) jr.getObject();
		// 输出结果
		System.out.println(result.get("id") + "-" + result.get("name") + "-"
				+ result.get("age") + "-" + result.get("message"));
	}
}

##3、Feign 框架介绍

  • Feign是一个Github上一个开源项目,目的:为了简化Web Service客户端的开发
  • 在使用Feign时,可以使用注解来修饰接口,被注解修饰的接口具有访问Web Service的能力
  • 注解包括了Feign自带的注解,也支持使用第三方的注解
  • Feign支持插件式的编码器和解码器,可以通过该特性,对请求和响应进行不同的封装与解析
  • SpringCloud将Feign集成到netflix项目中
  • 当与Eureka、Ribbon集成时,Feign就具有负载均衡的功能
  • Feign本身在使用上的简便性,加上与SpringCloud的高度整合,使用该框架在SpringCloud中调用集群服务,将会大大降低开发的工作量

第一个feign程序: Maven:

 <!--feign 依赖 start-->
 <dependency>
     <groupId>io.github.openfeign</groupId>
     <artifactId>feign-core</artifactId>
     <version>9.5.0</version>
 </dependency>
 <dependency>
     <groupId>io.github.openfeign</groupId>
     <artifactId>feign-gson</artifactId>
     <version>9.5.0</version>
 </dependency>
 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <version>1.18.2</version>
 </dependency>
 <!--feign 依赖 end -->
/**
 * 第一个Feign程序的测试接口
 * HelloClient 表示一个服务接口,在接口的 sayHello 方法中使用了@RequestLine 注解,
 * 表示使用 GET 方法向/hello 发送请求。
 */
public interface HelloClient {

    @RequestLine("GET /hello")
    String sayHello();
}

 /**
  * 第一个Feign程序
  */
 public static void main(String[] args) {
     //调用 Hello 接口
     HelloClient hello = Feign.builder().target(HelloClient.class, "http://localhost:8888/");
     System.out.println(hello.sayHello());
 }
    
  • 使用Feign创建HelloClient接口的实例,最后调用接口定义的方法\
  • Feign实际上会帮我们动态生成代理类
  • Feign使用的是JDK的动态带i,生成的代理类,会将请求的信息封装,交给feign.Client接口发送请求,而该接口默认实现类,最终会使用java.net.HttpURLConnection来发送Http请求

feign 请求参数与返回对象

public interface PersonClient {

    @RequestLine("GET /person/{personId}")
    Person findById(@Param("personId") Integer personId);

    //为所有属性加上 setter getter 等方法
    @Data
    class Person {
        Integer id;
        String name;
        Integer age;
        String message;
    }

}

/**
 * 第一个Feign程序
 * Exception in thread "main" feign.codec.DecodeException: java.lang.NumberFormatException: For input string: "张三"   因为Persion字段类型 服务端 客户端 不一致改一致就好了
 */
public static void main(String[] args) {
    //调用 Hello 接口
    PersonClient personService = Feign.builder()
            .decoder(new GsonDecoder())
            .target(PersonClient.class, "http://localhost:8888/");

    PersonClient.Person person = personService.findById(2);

    System.out.println(person.id);
    System.out.println(person.name);
    System.out.println(person.age);
    System.out.println(person.message);

}

在调用 Person 服务的运行类中添加了解码器的配置, GsonDecoder 会将返回的 JSON 字符串转换为接口方法返回的对象,关于解码器的内容,将在后面 节中讲述。