最近,在使用spring cloud框架时,发现feign也能实现三方请求,而且实现很简单,请求接口的结构很清晰,便果断学习一波。

记录一下。本次使用的依赖仅有openfeign。

Feign调用的简单实现

maven依赖

    <!-- openfeign依赖 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

Feign配置方式

feign有三种使用方式,前一种多是用于无需配置的微服务内部调用,后两者是用于自定义配置的三方调用或者内部微服务调用。

1. 默认模式,不使用配置类,作用于服务内部调用而非三方请求接口

这种情况下,如果不需要给注册中心的微服务添加额外的参数配置,那么可以不使用配置类,直接在yml配置打开feign开关即可。

此时默认使用SpringMVC契约模式。如下代码中,yml配置为用户中心的配置文件。

如果一个业务中心想要根据用户id查询用户信息,那么便可以直接根据用户中心的服务名定位,如UserService 类中的@FeignClient配置,注册中心会自动根据服务名寻址到用户中心的地址。

# 用户中心的服务名
spring:
  application:
    name: user-service
 
# 注册中心
eureka:
  instance:
    prefer-ip-address: true
    hostname: localhost
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka/
 
# feign
feign:
  httpclient:
    enabled: true
@FeignClient(name = "user-service", fallback = UserServiceHystrix.class)
public interface UserService {
 
  @GetMapping("/user/getUserById")
  Result getUserById(@RequestParam("id") String id);
}

2.自定义配置类

自定义配置类时, 直接在feign的配置类上加@Configuration注解,该注解的方式是全局的,对于所有由@FeignClient注解的调用类都生效。

这样的好处在于,调用项目注册中心的其他服务时不用频繁的手动去加载配置类。该配置类也会被加载到spring cloud feign的服务调用中。

不过,比较致命的是,调用外部API时有可能会和微服务调用之间产生冲突。

Feign契约不支持SpringMVC契约,在feign契约下使用springMVC注解时,spring注解的部分功能会失效,甚至导致创建bean失败等。

(大部分java.lang.IllegalStateException: Method getAllUrl not annotated with HTTP method type (ex. GET, POST) 异常都是由于契约问题造成的。)

3.自定义配置类法2 

自定义配置类时,另一种则是不使用注解对配置类加以标识,而是在@FeignClient的注解中添加配置参数,在需要调用外部API接口的feign调用类里手动加载该配置,加载方式如后文中ApiService服务所示。

使用这种方式能将项目同注册中心的服务与外部API区分开来。

但是需要每一个feign类去手动加载该配置。@FeignClient参数会在下文中讲到。

4. @FeignClient参数说明

@FeignClient用来修饰类、接口类、注解类等。它的所有参数如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {
  @AliasFor("name")
  String value() default "";
 
  /** @deprecated */
  @Deprecated
  String serviceId() default "";
 
  String contextId() default "";
 
  @AliasFor("value")
  String name() default "";
 
  String qualifier() default "";
 
  String url() default "";
 
  boolean decode404() default false;
 
  Class<?>[] configuration() default {};
 
  Class<?> fallback() default void.class;
 
  Class<?> fallbackFactory() default void.class;
 
  String path() default "";
 
  boolean primary() default true;
}
  • value:服务名,访问第三方接口时可以随便命名。支持从配置文件中获取配置。
  • name:请求的服务名(用于微服务时,请求其他服务名的名称)。
  • url:第三方请求地址,支持从配置文件中获取配置。
  • fallback:失败时请求的回调类,熔断处理。
  • configuration:手动加载feign配置类。

5. 自定义配置的简单实现

A. Feign配置类

// 增加该配置时,该配置类就变成全局配置类
// @Configuration
public class FeignConfig implements RequestInterceptor {
 
  @Autowired
  private ObjectFactory<HttpMessageConverters> messageConverters;
 
  @Bean
  public Contract feignContract() {
    // feign 契约 @RequestLine
    return new Contract.Default();
    // springMVC契约 @GetMapping @PostMapping 等
    // return new SpringMvcContract();
  }
 
  // 记录请求和响应的头文件,正文和元数据的日志,需要在配置文件指出需要打印日志的类
  @Bean
  Logger.Level feignLoggerLevel() {
    return Logger.Level.FULL;
  }
 
  // 连接超时时间说明:连接超时时间,单位分钟,读取超时时间,单位秒,重定向为是
  @Bean
  public Options options() {
    return new Options(10, TimeUnit.MINUTES, 60, TimeUnit.SECONDS, true);
  }
 
  // 编码方式
  @Bean
  public Encoder feignFormEncoder() {
    return new SpringFormEncoder(new SpringEncoder(messageConverters));
  }
 
  // (全局设置)设置请求头等业务需要参数。
  @Override
  public void apply(RequestTemplate template) {
 
  }
}

B. 配置文件

使用yml文件配置。Feign默认使用URLConnection发送HTTP请求。可以通过配置文件修改他的http发送方式如:httpclient、okhttp等。可以根据自己的需求进行修改。

server:
  port: 8080
 
#设置feign请求方式
feign:
  httpclient:
    enabled: true
 
# 打开debug请求日志 可以使用的参数有info warn error debug等
logging:
  level:
    com.example.feign.feign.ApiService: debug
 
# 第三方请求地址
api:
  url: https://api.apiopen.top

C. 正式使用,feign无参数GET方式 请求三方接口

该部分的测试接口都是基于开源社区的测试接口。使用很久了,再次感谢一下开源社区大佬们的幸苦付出。现在有好多接口都用不了。希望大家不要恶意刷接口。

请求方式:GET

请求地址:https://api.apiopen.top/getSingleJoke

方法上使用的注解是feign契约(Contract)RequestLine。要使用Spring契约 GetMapping 等注解时,需要在FeignConfig中配置即可。

ApiService类代码如下:

@FeignClient(value = "api-service", url = "${api.url}"
    , fallback = ApiServiceHystrix.class, configuration = FeignConfig.class)
public interface ApiService {
 
  /**
   * 平台接口预览 方法名可以随便取
   */
  @RequestLine("GET /getAllUrl")
  List<String> getAllUrl();
 
}

ApiServiceHystrix类代码:

public class ApiServiceHystrix implements ApiService {
 
  @Override
  public List<String> getAllUrl() {
    // 设置调用失败时的降级处理
    return null;
  }
}

调用写好的接口,查看参数:

调用成功!Feign的基础调用很简单,如果需要调用多个相同地址的第三方请求,只需要新增方法即可,无需再增加额外的配置。

但仅仅用于单次调用时,feign比起其他HTTP请求方式又稍显麻烦,不过胜在简洁明了。

6. Feign 的其他请求方式

  • Query参数

请求方式:POST

请求地址:https://api.apiopen.top/getImages

现在尝试用feign来进行Query请求。请求成功后,用于接收数据的对象可以是一个Java 对象类,也可以是JSONObject对象。当返回内容结构稳定时(成功失败所返回的数据格式相同时),Java对象才能准确接收到信息。

创建一个结果类:

@Data
public class ApiResult implements Serializable {
 
  private static final long serialVersionUID = 1L;
 
  private Integer code;
 
  private String message;
 
  private List result;
 
}

ApiService类中增加对应方法:

  @RequestLine("POST /getImages?page={page}&count={count}")
  ApiResult getImages(@Param("page") String page, @Param("count") String count);

请求结果:

  • POST表单

post表单请求发送时,请求参数要为Map类型的键值对。示例代码:

  @RequestLine("POST /deleteFeedback")
  ApiResult deleteFeedback(@RequestBody Map<String, ?> bodyMap);
  • 设置Header请求头

请求头可以通过feign注解 @HeaderMap(import feign.HeaderMap;)示例代码:

  @RequestLine("POST /requestHeader")
  JSONObject getTcText(@HeaderMap Map<String, Object> headers, @RequestBody Map<String, Object> map);

其他请求可移步git:open-feign

以上为个人经验,希望能给大家一个参考,也希望大家多多支持Devmax。

Feign如何实现第三方的HTTP请求的更多相关文章

  1. 通过AFNetworking 2.0上传iOS图像

    我一直在寻找新的AFNetworking2.0上传图像的例子.但是我正在撞墙,无法弄清楚代码有什么问题.所以这是我使用的代码TIA解决方法我最终使用了多部分请求

  2. ios – 在Objective-C中发送分块的HTTP 1.1请求

    我有以下问题:我正在创建一个非常大的SOAP请求(数据是一个编码为Base64字符串的视频),因此我不能将其作为原始SOAP请求发送,而是需要在HTTP1.1块中发送它.我似乎无法弄明白该怎么做.我在这里使用了代码:WhatarealternativestoNSURLConnectionforchunkedtransferencoding但它似乎没有做我认为应该做的事情–我可以看到请求作为单个请求

  3. ios – Swift2.0 HTTP请求无法正常工作

    参见英文答案>TransportsecurityhasblockedacleartextHTTP23个HelloStackoverflow,我将swift应用程序移动到Swift2.0后,我不断收到此错误:我看了下面的链接https://forums.developer.apple.com/thread/5835并将以下代码添加到我的info.plist中它仍然不起作用,任何人都有替代解决方案?解

  4. 如何在Swift语言中创建http请求

    概述:本文通过实例从同步和异步两种方式上回答了”如何在Swift语言中创建http请求“的问题。如果你对Objective-C比较了解的话,对于如何创建http请求你一定驾轻就熟了,而新语言Swift与其相比只有语法上的区别。但是,对才接触到这个崭新平台的初学者来说,他们仍然想知道“如何在Swift语言中创建http请求?”。在这里,我将作出一些建议来回答上述问题。常见的创建http请求的方式主要

  5. Swift HTTP请求集合

    )->Voidinprintln})带参数的get请求varrequest=HTTPTask()request.GET("http://google.com",parameters:["param":"param1","array":["firstarrayelement","second","third"],"num":23],arial;font-size:14px;line-height:21px">println("response:\(response.responSEObject!)")POS

  6. swift 自带HTTP请求

    )->Voidiniferror!=nil{println(error)}else{println(data)}}funcHTTPGet(url:String,callback:(String,String?)->Void){varrequest=NSMutableuRLRequest(URL:NSURL(string:url)!)HTTPsendRequest(request,callback)}funcHTTPsendRequest(request:NSMutableuRLRequest,callba

  7. Swift-网络请求http的基础学习

    swift发起网络请求自然有他自己的处理类NSURLRequest。这个跟android中httpClient的作用都是一样的。因此本篇博客只是记录一下这个过程,代码比较简单。这里封装了一个处理请求的httpController类。这个请求时异步处理的值得注意的是我写了一个delegate类来数据回调。viewcontroller顾名思义就是一个控制器,为了遵循MVC思想原则,我们不应该在控制器中写太多的逻辑代码,可以交给model层来出来,控制器负责调用就可以。这样代码更加易读。

  8. openstack swift和wsgi源码分析1 HTTP请求处理过程

    分析proxy-server代理服务的执行流程,其他的三个主要服务accountserver,containerserver,objectserver执行过程通proxyserver类似。入口函数调用run_wsgi,此函数完成以下工作:下面重点研究下process_request函数是如何把消息转化为HTTP的request对象这一过程。process_request函数,生成HttpProtocol对象,并执行init操作,注意,HttpProtocol对象自身没有init函数,所以会调用父类的父类的

  9. Swift: 用Alamofire做http请求,用ObjectMapper解析JSON

    ObjectMapper是一个双向的转化工具。最外面的一层是:所以对应的model定义是这样的:最重要的是先importObjectMapper。这样ObjectMapper就知道应该如何解析json字符串到对应的类对象中了。除了上面提到的,ObjectMapper还有很多其他的功能。最开始介绍使用Alamofire请求并成功返回之后,我们只是把字符串打印了出来。response.result.value取出了http请求之后返回的json串。不过Github奇葩的返回的结果就是一个JSONArray,居

  10. Swift 3中的HTTP请求

    asURL).你想用感叹号解开什么(!什么是变量名称?很多类名在Swift2和3之间发生了变化,因此您找到的答案可能不适用.以下示例连接到httpbin.org以获取您的IP地址:

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部