持续创作,加速成长!这是我参与「掘金日新计划 · 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 字符串转换为接口方法返回的对象,关于解码器的内容,将在后面 节中讲述。