- feign、http,有时候在调用第三方api的时候、使用httpclient,别人的接口不可能提供它的配置,自己项目框架是spring的,使用feign相互配置,都是okhttpclient的方式。Feign是一个接口声明式调用框架,实现了一个抽象层的逻辑,没有真正实现底层http请求,提供了一个client接口用于实现底层http操作,默认提供的实现是基于httpurlconnection,也有基于apachehttpclient的实现,且feign具有分布式负载均衡功能
- feign的两种使用方法
- 在请求方法上添加请求头参数
- @FeignClient(name=”apiClient”,url=”${test.url}”,path=”api”)
- Public interface BasicApiClient{
- @getMapping
- void queryUser(@requestHeader(name=“token”)String token)
- }
- 注意多了一个header,相当于往请求头添加了一个token参数,适用于token动态变化的参数
- 利用@FeignClient的configuration属性
- Public class ClientConfiguration{
- @value(“${test.token}”)
- Private String token;
- @bean
- Public requestInterceptor headerInterceptor(){
- Retrun new requestInterceptor(){
- @overide
- Public void apply(requrestTemplate template){
- List<String> authorizationList=Lists.newArrayList(token);
- List<String> contentTypeList = Lists.newArrayList("application/x-www-form-urlencoded;charset=utf-8");
- Map<String, Collection<String>> headers = ImmutableMap.of("token", authorizationList, "Content-Type", contentTypeList);
- template.headers(headers);
- }
- }
- }
- 修改@feignClient
- 在请求方法上添加请求头参数
-
-
xviii.
@FeignClient(name = "apiClientTwo", url = "${test.url}", path = "api", configuration = ClientConfiguration.class)
-
- Feign原理实现
结构图
启动配置上检查是否有enablefeignclients注解,如果有,开启包扫描,扫描feignclient接口,扫描到后通过beandefinition注入到ioc容器中,方便被调用。
在feignclientsregister中,registerfeignclient完成了注册feign客户端的操作,包括注解时配置的所有信息。
Reflectivefeign内部使用了jdk动态代理为目标接口生成动态代理类,生成了一个invocationhandler的统一方法拦截器,同时为接口的每个方法生成一个synchronousmethodhandler拦截器,并解析方法上的元数据,通过requestTemplate生成一个http请求模板
始化扫包原理:
Feignclientfactorybean解析
代理实现
代理invoke的实际执行过程
- Httpclient原理:使用httpclient包
- 创建httpclient对象
- 创建request对象
- 使用httpclient执行request,得到response
- 处理response,关闭httpclient
- public void test01(){
- HttpClient httpClient = HttpClients.createDefault();
- String url = "https://www.cctv.com";
- HttpGet get = new HttpGet(url);
- try {
- HttpResponse httpResponse = httpClient.execute(get);
- //获取返回值状态信息
- int status = httpResponse.getStatusLine().getStatusCode();
- if(status == 200){
- //请求正确的. 获取响应结果
- HttpEntity entity = httpResponse.getEntity(); //获取响应对象的实体信息.
- //将实体对象转化为用户能够识别的字符串
- String result = EntityUtils.toString(entity,"UTF-8");
- System.out.println(result);
- }else{
- System.out.println("httpClient调用异常.");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- 使用httpclient解决的跨域问题:
- Ajax请求地址改为自己系统的后台地址,之后在自己后台用httpclient请求url