目录
简介
使用
基本使用
注解式拦截器
全局拦截器
配置
全局超时时间
全局请求重试
首页 Java java教程 SpringBoot中如何使用HTTP客户端工具Retrofit

SpringBoot中如何使用HTTP客户端工具Retrofit

May 12, 2023 am 11:55 AM
http springboot retrofit

简介

Retrofit是适用于AndroidJava且类型安全的HTTP客户端工具,在Github上已经有39k+Star。其最大的特性的是支持通过接口的方式发起HTTP请求,类似于我们用Feign调用微服务接口的那种方式。

SpringBoot中如何使用HTTP客户端工具Retrofit

SpringBoot是使用最广泛的Java开发框架,但是Retrofit官方并没有提供专门的Starter。于是有位老哥就开发了retrofit-spring-boot-starter,它实现了Retrofit与SpringBoot框架的快速整合,并且支持了诸多功能增强,极大简化开发。今天我们将使用这个第三方Starter来操作Retrofit。

SpringBoot中如何使用HTTP客户端工具Retrofit

使用

在SpringBoot中使用Retrofit是非常简单的,下面我们就来体验下。

依赖集成

有了第三方Starter的支持,集成Retrofit仅需一步,添加如下依赖即可。

<!--Retrofit依赖-->
<dependency>
    <groupId>com.github.lianjiatech</groupId>
    <artifactId>retrofit-spring-boot-starter</artifactId>
    <version>2.2.18</version>
</dependency>
登录后复制

基本使用

下面以调用mall-tiny-swagger中的接口为例,我们来体验下Retrofit的基本使用。

首先我们准备一个服务来方便远程调用,使用的是之前的mall-tiny-swagger这个Demo,打开Swagger看下,里面有一个登录接口和需要登录认证的商品品牌CRUD接口,

SpringBoot中如何使用HTTP客户端工具Retrofit

我们先来调用下登录接口试试,在application.yml中配置好mall-tiny-swagger的服务地址;

remote:
  baseUrl: http://localhost:8088/
登录后复制

再通过@RetrofitClient声明一个Retrofit客户端,由于登录接口是通过POST表单形式调用的,这里使用到了@POST@FormUrlEncoded注解;

/**
 * 定义Http接口,用于调用远程的UmsAdmin服务
 * Created by macro on 2022/1/19.
 */
@RetrofitClient(baseUrl = "${remote.baseUrl}")
public interface UmsAdminApi {
    @FormUrlEncoded
    @POST("admin/login")
    CommonResult<LoginInfo> login(@Field("username") String username, @Field("password") String password);
}
登录后复制

如果你不太明白这些注解是干嘛的,看下下面的表基本就懂了,更具体的话可以参考Retrofit官方文档;

SpringBoot中如何使用HTTP客户端工具Retrofit

接下来在Controller中注入UmsAdminApi,然后进行调用即可;

/**
 * Retrofit测试接口
 * Created by macro on 2022/1/19.
 */
@Api(tags = "RetrofitController", description = "Retrofit测试接口")
@RestController
@RequestMapping("/retrofit")
public class RetrofitController {
    @Autowired
    private UmsAdminApi umsAdminApi;
    @Autowired
    private TokenHolder tokenHolder;
    @ApiOperation(value = "调用远程登录接口获取token")
    @PostMapping(value = "/admin/login")
    public CommonResult<LoginInfo> login(@RequestParam String username, @RequestParam String password) {
        CommonResult<LoginInfo> result = umsAdminApi.login(username, password);
        LoginInfo loginInfo = result.getData();
        if (result.getData() != null) {
            tokenHolder.putToken(loginInfo.getTokenHead() + " " + loginInfo.getToken());
        }
        return result;
    }
}
登录后复制

为方便后续调用需要登录认证的接口,我创建了TokenHolder这个类,把token存储到了Session中;

/**
 * 登录token存储(在Session中)
 * Created by macro on 2022/1/19.
 */
@Component
public class TokenHolder {
    /**
     * 添加token
     */
    public void putToken(String token) {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
        request.getSession().setAttribute("token", token);
    }
    /**
     * 获取token
     */
    public String getToken() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
        Object token = request.getSession().getAttribute("token");
        if(token!=null){
            return (String) token;
        }
        return null;
    }
}
登录后复制

接下来通过Swagger进行测试,调用接口就可以获取到远程服务返回的token了,访问地址:http://localhost:8086/swagger-ui/

SpringBoot中如何使用HTTP客户端工具Retrofit

注解式拦截器

商品品牌管理接口,需要添加登录认证头才可以正常访问,我们可以使用Retrofit中的注解式拦截器来实现。

首先创建一个注解式拦截器TokenInterceptor继承BasePathMatchInterceptor,然后在doIntercept方法中给请求添加Authorization头;

/**
 * 给请求添加登录Token头的拦截器
 * Created by macro on 2022/1/19.
 */
@Component
public class TokenInterceptor extends BasePathMatchInterceptor {
    @Autowired
    private TokenHolder tokenHolder;
    @Override
    protected Response doIntercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (tokenHolder.getToken() != null) {
            request = request.newBuilder()
                    .header("Authorization", tokenHolder.getToken())
                    .build();
        }
        return chain.proceed(request);
    }
}
登录后复制

创建调用品牌管理接口的客户端PmsBrandApi,使用@Intercept注解配置拦截器和拦截路径;

/**
 * 定义Http接口,用于调用远程的PmsBrand服务
 * Created by macro on 2022/1/19.
 */
@RetrofitClient(baseUrl = "${remote.baseUrl}")
@Intercept(handler = TokenInterceptor.class, include = "/brand/**")
public interface PmsBrandApi {
    @GET("brand/list")
    CommonResult<CommonPage<PmsBrand>> list(@Query("pageNum") Integer pageNum, @Query("pageSize") Integer pageSize);
    @GET("brand/{id}")
    CommonResult<PmsBrand> detail(@Path("id") Long id);
    @POST("brand/create")
    CommonResult create(@Body PmsBrand pmsBrand);
    @POST("brand/update/{id}")
    CommonResult update(@Path("id") Long id, @Body PmsBrand pmsBrand);
    @GET("brand/delete/{id}")
    CommonResult delete(@Path("id") Long id);
}
登录后复制

再在Controller中注入PmsBrandApi实例,并添加方法调用远程服务即可;

/**
 * Retrofit测试接口
 * Created by macro on 2022/1/19.
 */
@Api(tags = "RetrofitController", description = "Retrofit测试接口")
@RestController
@RequestMapping("/retrofit")
public class RetrofitController {
    @Autowired
    private PmsBrandApi pmsBrandApi;
    @ApiOperation("调用远程接口分页查询品牌列表")
    @GetMapping(value = "/brand/list")
    public CommonResult<CommonPage<PmsBrand>> listBrand(@RequestParam(value = "pageNum", defaultValue = "1")
                                                        @ApiParam("页码") Integer pageNum,
                                                        @RequestParam(value = "pageSize", defaultValue = "3")
                                                        @ApiParam("每页数量") Integer pageSize) {
        return pmsBrandApi.list(pageNum, pageSize);
    }
    @ApiOperation("调用远程接口获取指定id的品牌详情")
    @GetMapping(value = "/brand/{id}")
    public CommonResult<PmsBrand> brand(@PathVariable("id") Long id) {
        return pmsBrandApi.detail(id);
    }
    @ApiOperation("调用远程接口添加品牌")
    @PostMapping(value = "/brand/create")
    public CommonResult createBrand(@RequestBody PmsBrand pmsBrand) {
        return pmsBrandApi.create(pmsBrand);
    }
    @ApiOperation("调用远程接口更新指定id品牌信息")
    @PostMapping(value = "/brand/update/{id}")
    public CommonResult updateBrand(@PathVariable("id") Long id, @RequestBody PmsBrand pmsBrand) {
        return pmsBrandApi.update(id,pmsBrand);
    }
    @ApiOperation("调用远程接口删除指定id的品牌")
    @GetMapping(value = "/delete/{id}")
    public CommonResult deleteBrand(@PathVariable("id") Long id) {
        return  pmsBrandApi.delete(id);
    }
}
登录后复制

在Swagger中调用接口进行测试,发现已经可以成功调用。

SpringBoot中如何使用HTTP客户端工具Retrofit

全局拦截器

如果你想给所有请求都加个请求头的话,可以使用全局拦截器。

创建SourceInterceptor类继承BaseGlobalInterceptor接口,然后在Header中添加source请求头。

/**
 * 全局拦截器,给请求添加source头
 * Created by macro on 2022/1/19.
 */
@Component
public class SourceInterceptor extends BaseGlobalInterceptor {
    @Override
    protected Response doIntercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request newReq = request.newBuilder()
                .addHeader("source", "retrofit")
                .build();
        return chain.proceed(newReq);
    }
}
登录后复制

配置

Retrofit的配置很多,下面我们讲讲日志打印、全局超时时间和全局请求重试这三种最常用的配置。

日志打印 默认配置下Retrofit使用basic日志策略,打印的日志非常简单;

SpringBoot中如何使用HTTP客户端工具Retrofit

我们可以将application.yml中的retrofit.global-log-strategy属性修改为body来打印最全日志;

retrofit:
  # 日志打印配置
  log:
    # 启用日志打印
    enable: true
    # 日志打印拦截器
    logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor
    # 全局日志打印级别
    global-log-level: info
    # 全局日志打印策略
    global-log-strategy: body
登录后复制

修改日志打印策略后,日志信息更全面了;

SpringBoot中如何使用HTTP客户端工具Retrofit

Retrofit支持四种日志打印策略;

  • NONE:不打印日志;

  • BASIC:只打印日志请求记录;

  • HEADERS:打印日志请求记录、请求和响应头信息;

  • BODY:打印日志请求记录、请求和响应头信息、请求和响应体信息。

全局超时时间

有时候我们需要修改一下Retrofit的请求超时时间,可以通过如下配置实现。

retrofit:
  # 全局连接超时时间
  global-connect-timeout-ms: 3000
  # 全局读取超时时间
  global-read-timeout-ms: 3000
  # 全局写入超时时间
  global-write-timeout-ms: 35000
  # 全局完整调用超时时间
  global-call-timeout-ms: 0
登录后复制

全局请求重试

retrofit-spring-boot-starter支持请求重试,可以通过如下配置实现。

retrofit:
  # 重试配置
  retry:
    # 是否启用全局重试
    enable-global-retry: true
    # 全局重试间隔时间
    global-interval-ms: 100
    # 全局最大重试次数
    global-max-retries: 2
    # 全局重试规则
    global-retry-rules:
      - response_status_not_2xx
      - occur_exception
    # 重试拦截器
    retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor
登录后复制

重试规则global-retry-rules支持如下三种配置。

  • RESPONSE_STATUS_NOT_2XX:响应状态码不是2xx时执行重试;

  • OCCUR_IO_EXCEPTION:发生IO异常时执行重试;

  • OCCUR_EXCEPTION:发生任意异常时执行重试。

以上是SpringBoot中如何使用HTTP客户端工具Retrofit的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

http状态码520是什么意思 http状态码520是什么意思 Oct 13, 2023 pm 03:11 PM

http状态码520是指服务器在处理请求时遇到了一个未知的错误,无法提供更具体的信息。用于表示服务器在处理请求时发生了一个未知的错误,可能是由于服务器配置问题、网络问题或其他未知原因导致的。通常是由服务器配置问题、网络问题、服务器过载或代码错误等原因导致的。如果遇到状态码520错误,最好联系网站管理员或技术支持团队以获取更多的信息和帮助。

http状态码403是什么 http状态码403是什么 Oct 07, 2023 pm 02:04 PM

http状态码403是服务器拒绝了客户端的请求的意思。解决http状态码403的方法是:1、检查身份验证凭据,如果服务器要求身份验证,确保提供正确的凭据;2、检查IP地址限制,如果服务器对IP地址进行了限制,确保客户端的IP地址被列入白名单或未列入黑名单;3、检查文件权限设置,如果403状态码与文件或目录的权限设置有关,确保客户端具有足够的权限访问这些文件或目录等等。

SpringBoot与SpringMVC的比较及差别分析 SpringBoot与SpringMVC的比较及差别分析 Dec 29, 2023 am 11:02 AM

SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

理解网页重定向的常见应用场景并了解HTTP301状态码 理解网页重定向的常见应用场景并了解HTTP301状态码 Feb 18, 2024 pm 08:41 PM

掌握HTTP301状态码的含义:网页重定向的常见应用场景随着互联网的迅猛发展,人们对网页交互的要求也越来越高。在网页设计领域,网页重定向是一种常见且重要的技术,通过HTTP301状态码来实现。本文将探讨HTTP301状态码的含义以及在网页重定向中的常见应用场景。HTTP301状态码是指永久重定向(PermanentRedirect)。当服务器接收到客户端发

如何使用Nginx Proxy Manager实现HTTP到HTTPS的自动跳转 如何使用Nginx Proxy Manager实现HTTP到HTTPS的自动跳转 Sep 26, 2023 am 11:19 AM

如何使用NginxProxyManager实现HTTP到HTTPS的自动跳转随着互联网的发展,越来越多的网站开始采用HTTPS协议来加密传输数据,以提高数据的安全性和用户的隐私保护。由于HTTPS协议需要SSL证书的支持,因此在部署HTTPS协议时需要有一定的技术支持。Nginx是一款强大且常用的HTTP服务器和反向代理服务器,而NginxProxy

快速应用:PHP 异步 HTTP 下载多个文件的实用开发案例分析 快速应用:PHP 异步 HTTP 下载多个文件的实用开发案例分析 Sep 12, 2023 pm 01:15 PM

快速应用:PHP异步HTTP下载多个文件的实用开发案例分析随着互联网的发展,文件下载功能已成为很多网站和应用程序的基本需求之一。而对于需要同时下载多个文件的场景,传统的同步下载方式往往效率低下且耗费时间。为此,使用PHP异步HTTP下载多个文件成为了一种越来越常见的解决方案。本文将通过一个实际的开发案例,详细分析如何使用PHP异步HTTP

C#中常见的网络通信和安全性问题及解决方法 C#中常见的网络通信和安全性问题及解决方法 Oct 09, 2023 pm 09:21 PM

C#中常见的网络通信和安全性问题及解决方法在当今互联网时代,网络通信已经成为了软件开发中必不可少的一部分。在C#中,我们通常会遇到一些网络通信的问题,例如数据传输的安全性、网络连接的稳定性等。本文将针对C#中常见的网络通信和安全性问题进行详细讨论,并提供相应的解决方法和代码示例。一、网络通信问题网络连接中断:网络通信过程中,可能会出现网络连接的中断,这会导致

http请求415错误解决方法 http请求415错误解决方法 Nov 14, 2023 am 10:49 AM

解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。

See all articles