Spring Boot入坑-7-后端HTTP请求
-
后端项目完成后,除了前后端分离模式的前端对后端请求的需要,如Vue通过Axios.js组件请求后端REST接口;不同后端系统中也需要进行相互的HTTP请求,实现各业务系统的业务交互;如订单服务,会调用支付服务、库存服务、积分服务等,如下图
后端HTTP请求图 -
JDK的java.net包中已经提供了访问HTTP协议的基本功能,主要是HttpUrlConnection,但是对于大部分应用程序来说,JDK库本身提供的功能还是不够丰富和灵活,会使用一些简单、灵活的工具
-
基于Spring Boot的HTTP请求工具主要有
-
Http Client:Apache下的HTTP请求子项目,相对复杂,可配置连接池等参数
-
OkHttp3:类似于Http Client,但性能更好,也可配置连接池等参数
-
RestTemplate:Spring下的Rest请求工具,方便使用,默认使用HttpUrlConnection,可集成OkHttp
-
OpenFeign: Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API
-
WebClient:非阻塞的基于响应式编程的进行Http请求的客户端工具,性能更好,Spring 5开始提供
-
RestTemplate
概述
-
RestTemplate是Spring 提供的用于访问其他REST服务的组件
-
RestTemplate 提供了多种便捷访问远程HTTP服务的方法,能够大大提高客户端的编写效率
-
底层默认使用HttpUrlConnection发送HTTP请求,可切换成其他性能更好的工具,如OkHttp3
-
可以添加拦截工具,对请求/响应进行相应处理,通过实现ClientHttpRequestInterceptor接口,并覆盖intercept方法,并添加到RestTemplate实现,比如,对每个请求添加token
-
特点
-
灵活,在程序中任意位置灵活使用
-
常用方法
-
getForXXX(),进行常用的GET请求操作
-
postForXXX(),进行常用的POST请求操作
-
exchange(),进行其他请求操作,因为针对其他HTTP请求操作,没有定义特别多的操作方式,使用通用的exchange()进行
使用步骤
-
定义请求拦截器,实现ClientHttpRequestInterceptor接口,并覆盖intercept方法,【可选】;见附件代码中的interceptor.RestTemplateClientHttpRequestInterceptor类
-
注入RestTemplate对象,注入RestTemplate对象到Spring容器,并可绑定请求拦截器;见附件代码中的config.RestTemplateConfig类
-
使用RestTemplate对象,其丰富的方法实现对其他REST服务进行调用;见附件代码中的remote.BugRemote类
【演示】
-
Spring Boot中使用RestTemplate对其他REST服务进行调用,见附件项目springboot-resttemplate中的类
-
config\RestTemplateConfig类,注入RestTemplate对象
-
remote\BugRemote类,使用RestTemplate对象
-
interceptor\RestTemplateClientHttpRequestInterceptor类,请求拦截器
-
OpenFeign
概述
-
Netflix开发的声明式、模板化的HTTP客户端,OpenFeign可以帮助我们更快捷、优雅地调用其他REST服务
-
默认使用HttpUrlConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接
-
可使用其他底层工具进行替换,比如Apache的Http Client或OkHttp3
-
特点
-
使用简单,但不够灵活,一般应用于固定接口调用,通过模拟成RestController形式进行调用
-
使用步骤
-
添加依赖:在pom.xml中引入依赖spring-cloud-starter-openfeign,注意版本匹配
<!--【OpenFeign】1、添加依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.1.8</version> </dependency>
-
添加启动注解:在启动类上添加@EnableFeignClients注解
-
定义远程服务匹配接口:定义与被调用第三方服务匹配的接口并添加注解@FeignClient,指定name和url,代码片断如下
/** * Bug远程调用类 * 【OpenFeign】3、定义远程服务匹配接口,使用配置在application.properties中的远程服务主机地址URL */ @FeignClient(name = "bug",url="${remoteprj.base_url}/bug") public interface BugRemote { }
-
定义远程服务匹配方法签名:在上一步定义的远程服务匹配接口中,定义与被调用第三方服务匹配的方法签名和映射,代码片断如下
/** * 分页查询 * 【OpenFeign】4、定义远程服务匹配方法签名 */ @GetMapping("/") ResponseData<List<BugOutputDto>> query(@RequestParam(defaultValue = "1")Long pageIndex,@RequestParam(defaultValue = "5") Long pageSize,@RequestParam Integer gradeId, @RequestParam String title);
-
添加调用日志:添加日志配置类,并在application.properties中添加放开debugger日志的配置,代码片断如下,【可选】
-
日志类
package com.example.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class OpenFeignConfig { /** * 【OpenFeign】5、添加调用日志,与application.properties中的配置配合使用 * @return */ @Bean Logger.Level feignLoggerLeave(){ return Logger.Level.FULL; } }
-
application.properties配置
#【OpenFeign】5、添加调用日志 feign.httpclient.enabled=true logging.level.com.example.remote.*=debug
-
-
添加请求拦截器,实现RequestInterceptor接口,覆盖apply方法,添加@Component注解自动注入到Spring容器,在方法中往请求中添加请求信息,代码片断如下,【可选】
package com.example.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 【OpenFeign】6、添加请求拦截器,【可选】 */ @Component @Slf4j public class OpenFeignRequestInterceptor implements RequestInterceptor { //配置的Token @Value("${remoteprj.token}") String token; @Override public void apply(RequestTemplate template) { //添加请求日志 log.info("【OpenFeign】请求拦截"); //请求添加Token template.header("token",token); } }
-
使用远程服务:在需要使用的地方使用自动装配第3步定义的接口,并使用匹配签名方法,即可实现对远程服务的调用
【演示】
-
Spring Boot中使用OpenFeign对其他REST服务进行调用,见附件项目springboot-openfeign中的类
-
启动类,添加@EnableFeignClients注解
-
remote\BugRemote类,使用OpenFeign功能
-
interceptor\OpenFeignRequestInterceptor类,拦截器类
-
config\OpenFeignConfig类,配置application.properties,添加调用日志
-
代码
网盘地址:链接:https://pan.baidu.com/s/1wu7I1oiMC50MESKysOuGqQ?pwd=8888