Java 如何使用Feign发送HTTP请求

在往常的 HTTP 调用中,一直都是使用的官方提供的 RestTemplate 来进行远程调用,该调用方式将组装代码冗余到正常业务代码中,不够优雅,因此在接触到 Feign 后,考虑使其作为一个 HTTP 发送基础,来进行远程调用。

下面就让我们来看一下,其是如何使用的。

引入依赖

首先,我们需要将 Feign 的基础依赖引入项目,因为我们只使用 Feign 的 remote 功能,因此,只引入基础依赖。

此外在项目中,我们还自定义了了 JSON 转换和 log 设置,因此还需要引入这些的第三方依赖,如下所示。

   <!-- feign -->
    <dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-core</artifactId>
      <version>10.10.1</version>
    </dependency>
    <dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-gson</artifactId>
      <version>10.10.1</version>
    </dependency>
    <dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-slf4j</artifactId>
      <version>10.10.1</version>
    </dependency>

发送路径和方法设置

然后,因为 Feign 是一种申明式的调用,因此我们需要配置发送的接口路径和发送接口定义,看下面的例子。

  @RequestLine("GET /user/getone?arkOrgId={arkOrgId}&userId={userId}")
  JSONObject getOneStaff(@Param("arkOrgId") String arkOrgId,@Param("userId") String userId);

  @RequestLine("POST /user/add")
  @Headers("Content-Type: application/json")
  @Body("{body}")
  JSONObject saveStaff(@Param("body") SaveEmployeeDTO saveEmployeeDTO);

在代码实例中,我们定义了两种发送的实例,一种是 GET 请求,一种是 POST 请求,下面,我们分别来看一下其中的代码的作用是什么。

  • @RequestLine:定义发送方式和发送接口定义,其中用 GET 和 POST 来定义发送方式,然后空格后,写上 servelt path(context path 和域名或ip端口号在其他地方配置);
  • {}:用来作为占位符,动态填充需要的参数;
  • @Param:用来匹配 URI 中的占位符;
  • @Headers("Content-Type: application/json"):构建请求表头,在 POST 请求中,需要声明该请求的发送格式为 json;
  • @Body:POST 请求,需要标注请求体;
  • JSONObject:在本实例中,采用是一个通用的 json 对象来接收,方便统一,在自己的代码中,也可以定义一个接受实体类来接受,作用是一样的。

POST 请求,需要在实体中重写 toString() 方法,使其在发送时调用该方法后,是一个 JSON 字符串,详细见后文 Tips 中写的。

定义发送客户端

@Configuration
public class FeignConfig {
  public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
  @Value("${staff.base.url}")
  private String staffBaseUrl;
  @Bean
  public StaffFeignService staffFeignService() {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat(DATE_TIME_FORMAT);
    return Feign.builder()
        .retryer(closeFeignRetry())
        .decoder(new GsonDecoder(builder.create()))
        .encoder(new GsonEncoder())
        .logger(new Slf4jLogger())
        .logLevel(Logger.Level.FULL)
        .target(StaffFeignService.class, staffBaseUrl);
  }
  /**
   * 关闭feign的失败重试功能
   */
  @Bean
  public Retryer closeFeignRetry() {
    return Retryer.NEVER_RETRY;
  }

  @Bean
  public Request.Options options() {
    return new Request.Options(15000, 30000);
  }
}

紧接着,我们来定义发送客户端。

首先,我们采用 @Value 来动态添加路由,这样,就可以根据在配置文件中的属性来添加 context path,从而做到可拓展。

然后,feign 的很多配置都是可以根据自身项目需要在 DIY 的,因此在这里,我们配置了编解码采用 GSON 的编解码器,日志级别设置全打印。通过该设置来生成一个 Feign 客户端。

Feign 官方文档,在官方文档中,有详细的配置说明,根据自身需要使用,即可。

使用

@Autowired
StaffFeignService staffFeignService;

// get 请求
JSONObject saveSingleQrCode = staffFeignService.saveSingleQrCode(userId);

// post 请求
SaveMultiQrCodesDTO saveMultiQrCodesDTO = new SaveMultiQrCodesDTO();;
JSONObject saveMultiQrCodes = staffFeignService.saveMultiQrCodes(saveMultiQrCodesDTO);

通过该方式,即可发送对应请求。

Tips

记录一些在使用中的重点,需要注意。

重写 toString() 方法
在发送 JSON 时,需要重写 toString() 方法,否则会导致接受方,无法用 json 进行解析。

  @Override
  public String toString() {
    return JSON.toJSONString(this);
  }

异步客户端

有时候,我们使用异步发送,从而不影响我们的主体业务,Feign 也支持该种配置。

  @Bean
  public IHermesFeignService hermesFeignService() {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat(DATE_TIME_FORMAT);
    return AsyncFeign.asyncBuilder()
        .decoder(new GsonDecoder(builder.create()))
        .encoder(new GsonEncoder(builder.create()))
        .logger(new Slf4jLogger())
        .logLevel(Logger.Level.FULL)
        .target(IHermesFeignService.class, hermesBaseUrl);
  }

重点,就是在构建 Feign 时,采用 AsyncFeign.asyncBuilder() 来进行构建。

以上就是Java 如何使用Feign发送HTTP请求的详细内容,更多关于使用Feign发送HTTP请求的资料请关注我们其它相关文章!

(0)

相关推荐

  • Spring Cloud 系列之服务调用 OpenFeign的实现

    1.1 简介 1.1.1 概述   Feign 旨在使编写 Java Http 客户端变得更容易.在使用 Ribbon + RestTemplate 时,利用 RestTemplate 对 http 请求的封装处理,形成了一套模版化的调用方法.但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用.所以,Feign 在 Ribbon 基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义.在

  • SpringCloud Feign转发请求头(防止session失效)的解决方案

    微服务开发中经常有这样的需求,公司自定义了通用的请求头,需要在微服务的调用链中转发,比如在请求头中加入了token,或者某个自定义的信息uniqueId,总之就是自定义的一个键值对的东东,A服务调用B服务,B服务调用C服务,这样通用的东西如何让他在一个调用链中不断地传递下去呢?以A服务为例: 方案1 最傻的办法,在程序中获取,调用B的时候再转发,怎么获取在Controller中国通过注解获取,或者通过request对象获取,这个不难,在请求B服务的时候,通过注解将值放进去即可:简代码如下: 获取

  • Spring Cloud Feign组成配置过程解析

    Feign的组成 接口 作用 默认值 Feign.Builder Feign的入口 Feign.Builder Client Feign底层用什么去请求 和Ribbon配合时:LoadBalancerFeignClient 不和Ribbon配合时:Fgien.Client.Default Contract 契约,注解支持 SpringMVCContract Encoder 解码器,用于将独享转换成HTTP请求消息体 SpringEncoder Decoder 编码器,将相应消息体转成对象 Res

  • 解决Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题

    LocalDate . LocalTime . LocalDateTime 是Java 8开始提供的时间日期API,主要用来优化Java 8以前对于时间日期的处理操作.然而,我们在使用Spring Boot或使用Spring Cloud Feign的时候,往往会发现使用请求参数或返回结果中有 LocalDate . LocalTime . LocalDateTime 的时候会发生各种问题.本文我们就来说说这种情况下出现的问题,以及如何解决. 问题现象 先来看看症状.比如下面的例子: @Sprin

  • 解决Spring Cloud Feign 请求时附带请求头的问题

    问题描述 Feign 在请求时是不会将 request 的请求头带着请求的,导致假如 Feign 调用的接口需要请求头的信息,比如当前用户的 token 之类的就获取不到 解决方案 FeignConfiguration 通过实现 Feign 的 RequestInterceptor 将从上下文中获取到的请求头信息循环设置到 Feign 请求头中. /** * feign 配置文件 * 将请求头中的参数,全部作为 feign 请求头参数传递 * @author: linjinp * @create

  • Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 代码实践

    基于 spring-boot-starter-parent 2.1.9.RELEASE, spring-cloud-openfeign 2.1.3.RELEASE 引子 Feign 是一个声明式.模板化的HTTP客户端,简化了系统发起Http请求.创建它时,只需要创建一个接口,然后加上FeignClient注解,使用它时,就像调用本地方法一样,作为开发者的我们完全感知不到这是在调用远程的方法,也感知不到背后发起了HTTP请求: /** * @author axin * @suammry xx 客

  • java使用Feign实现声明式Restful风格调用

    一.Feign简介 Feign是netflix开发的声明式.模板化的http客户端,在使用时就像调用本地(服务消费者自己)的方法一般,帮助我们更加优雅的调用服务提供者的API.Feign自身支持springMVC,还整合了Eureka.Ribbon,极大的简化了Feign的使用.就整合Euraka而言,只需和普通的服务配置Eureka server的信息即可.整合Ribbon,就意味着不再需要通过标注@LoadBalanced的实例化后的RestTemplate去调用服务提供者方法了.Feign

  • SpringCloud Feign服务调用请求方式总结

    前言 最近做微服务架构的项目,在用feign来进行服务间的调用.在互调的过程中,难免出现问题,根据错误总结了一下,主要是请求方式的错误和接参数的错误造成的.在此进行一下总结记录.以下通过分为三种情况说明,无参数,单参数,多参数.每种情况再分get和post两种请求方式进行说明.这样的话,6种情况涵盖了feign调用的所有情况. 有个建议就是为了保证不必要的麻烦,在写feign接口的时候,与我们的映射方法保持绝对一致,同时请求方式,请求参数注解也都不偷懒的写上.如果遵循这种规范,可以避开90%的调

  • springboot FeignClient注解及参数

    一.FeignClient注解 FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上 @FeignClient(name = "github-client", url = "https://api.github.com", configuration = GitHubExampleConfig.class) public interface GitHubClient { @Request

  • Java探索之Feign入门使用详解

    一,简介 Feign使得 Java HTTP 客户端编写更方便.Feign 灵感来源于Retrofit.JAXRS-2.0和WebSocket.Feign最初是为了降低统一绑定Denominator到HTTP API的复杂度,不区分是否支持Restful.Feign旨在通过最少的资源和代码来实现和HTTP API的连接.通过可定制的解码器和错误处理,可以编写任意的HTTP API. Maven依赖: <!-- https://mvnrepository.com/artifact/com.netf

  • 如何基于springcloud模拟RPC调用(Feign)

    Feign简介 Feign是一个声明式的Web Service客户端,它能够让Web Service客户端的编写变得更加容易(你只需创建一个接口,并在接口上添加相应注解即可).除了Feign自带的注解外它还支持JAX-RS注解,SpringCloud又为Feign增加了对SpringMVC注解的支持,同时为了能够使用和Spring Web中默认使用的相同的httpMessageConverter,SpringCloud集成了Ribbon和Eureka,用来在使用Feign时能够为其提供一个负载均

随机推荐