拆分成 声明式
服务调用
什么声明式?
可以从编程范式入手了解:
编程范式:
声明式编程范式:声明式编程表明想要实现什么目的,应该做什么,但是不指定具体怎么做。
注: 非官方解释
声明式服务调用: 声明调用的URL地址,请求方式,和返回结果,但具体如何调用交给底层实现.
使用Feign,只需要声明一个接口即可,不需要关心传参、发送请求、获取响应内容、关闭连接等细节,Feign全部帮我们做好了。
SpringCloud集成了Feign组件,使得SpringCloud服务间调用变得更简单,方便
这里并不是SpringCloud的项目,那如何引入Feign到普通的SpringMVC项目中呢?
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-core -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-gson -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>10.2.0</version>
</dependency>
这里使用YesAPI作为第三方服务调用测试
这里以全国大学接口为例:
可以根据大学名称、学校类型、所在省份、所在城市等搜索大学
请求(查找全部师范大学):
http://api.yesapi.cn/?s=App.Common_University.Search&school_name=师范&app_key={你的app_key}&sign={动态签名}
返回:
{
"ret": 200,
"data": {
"err_code": 0,
"err_msg": "",
"schools": [
{
"school_name": "北京师范大学",
"school_province": "北京",
"school_level": "本科",
"school_website": "http://www.bnu.edu.cn/",
"school_city": "北京市"
}...
]
},
"msg": "当前请求接口:App.Common_University.Search"
}
可以看到小白开放平台是有统一返回体的,我们可以封装起来,也可以直接用Object或者Map来接收数据.我选择数据封装.
YesResponse.java
@Data
public class YesResponse<T> {
private Integer ret;
private String msg;
private T data;
}
YesUniversity.java
@Data
public class YesUniversity {
private String err_code;
private String err_msg;
private List<School> schools;
}
School.java
@Data
public class School {
private String school_name;
private String school_province;
private String school_level;
private String school_website;
private String school_city;
}
既然是声明式服务调用,必须先声明再调用,结果已经声明了,接下来就是声明参数了,我依然选择数据封装;
可以从上面的请求示例看到,需要3个参数.
YesVo.java
@Data
public class YesVo {
private String school_name;
private String app_key;
private String sign;
}
参数和结果都已经封装好了,接下来就是声明服务接口了
一般是根据对方的uri命名接口
Yes.java
public interface Yes {
@RequestLine("POST /?s=App.Common_University.Search")
YesResponse<YesUniversity> appCommonUniversitySearch(@QueryMap YesVo vo);
}
如上,一个服务接口已经声明好了,因为这里使用的是post请求,@QueryMap可以把对象转为body体的参数,@RequestLine可以声明其服务路径
通过service层的封装,可以把一些业务逻辑写在里面
public class YesService {
public YesResponse<YesUniversity> appCommonUniversitySearch(){
Yes yes=Feign.builder().decoder(new GsonDecoder()).target(Yes.class,"http://api.yesapi.cn");
YesVo yesVo=new YesVo();
yesVo.setSchool_name("师范");
yesVo.setApp_key("你的app_key");
yesVo.setSign("你的sign");
return yes.appCommonUniversitySearch(yesVo);
}
public static void main(String[] args) {
YesService yesService = new YesService();
YesResponse<YesUniversity> yesUniversityYesResponse = yesService.appCommonUniversitySearch();
System.out.println(JSON.toJSONString(yesUniversityYesResponse));
}
}
那出现400,500这些异常怎么办?
Feign组件考虑到了,Feign封装了一个Exception叫FeignException
结构如下图:这样我们可以通过这个FeignException的内置API达到我们对接服务的效果.
如果是同一个平台的服务,可以直接在对应的接口上增加接口方法:比如Yes接口
@RequestLine("GET ?service={service}&app_key={appKey}&sign={sign}")Result<JokeInfo<String>> res(@Param("service") String service,@Param("appKey") String appKey, @Param("sign") String sign);
如上的GET请求的写法,也是可以支持的.
使用Feign还有更多的用法,可以参考其官方的用法,传送门
vice") String service,@Param(“appKey”) String appKey, @Param(“sign”) String sign);
**如上的GET请求的写法,也是可以支持的.**
### 3.更多的用法
使用Feign还有更多的用法,可以参考其官方的用法,[传送门](https://github.com/OpenFeign/feign)