当前位置:

首页 > 编程开发 > SpringBoot中如何使用HTTP客户端工具Retrofit

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

简介Retrofit是适用于Android和Java且类型安全的HTTP客户端工具,在Github上已经有39k+Star。其最大的特性的是支持通过接口的方式发起HTTP请求,类似于我们用Feign调用微服务接口的那种方式。SpringBoot是使用最广泛的Java开发框架,但是Retrofit官方并没有提供专门的Starter。于是有位老哥就开发了retrofit-spring-boot-starter,它实现了Retrofit与SpringBoot框架的快速整合,并且支持了诸多功能增强,极大简化开发。

本文目录

    简介

    Retrofit是适用于Android和Java且类型安全的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仅需一步,添加如下依赖即可。

    
    
        com.github.lianjiatech
        retrofit-spring-boot-starter
        2.2.18
    

    基本使用

    下面以调用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 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 login(@RequestParam String username, @RequestParam String password) {
            CommonResult 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> list(@Query("pageNum") Integer pageNum, @Query("pageSize") Integer pageSize);
        @GET("brand/{id}")
        CommonResult 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> 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 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:发生任意异常时执行重试。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    前端获取http状态码400的返回值实例
    前端获取http状态码400的返回值实例

    调用后端接口遇到400状态码时,仅捕获error.message无法获取具体错误信息。需在catch中通过error.response对象获取状态码、响应体及业务描述等详细数据,从而精准定位后端返回的业务错误。

    suse 10.3 安装http apche2时遇到的rpm依赖问题的解决方法
    suse 10.3 安装http apche2时遇到的rpm依赖问题的解决方法

    在SUSE 10.3中安装http apache2的依赖问题解决 在SUSE 10.3系统上安装Apache2时,很多人都会遇到一个典型的依赖错误。系统会明确提示你缺少几个关键的库文件,具体信息通常是这样: libapr1 >= 1.0 is needed by apache2-2.2.3-16.2

    Golang 测试 HTTP API 方法详解
    Golang 测试 HTTP API 方法详解

    使用httptest可高效测试GolangHTTPAPI。1.用NewRecorder模拟请求并检查状态码、响应体和头信息;2.测试路由和中间件时将ServeMux注入测试;3.用NewServer启动临时服务进行端到端验证。

    HTTP状态码大全及常见问题解析
    HTTP状态码大全及常见问题解析

    前言通过前面的总结,我们了解到,当客户端通过HTTP向服务端发送请求后,期望服务端能够作出响应。在服务端的响应中,信息头包含一个称为StatusCode的属性,其值是一个三位数字,我们称之为HTTP状态码。HTTP状态码是HTTP协议的重要组成部分,用来表示服务端对当前请求的响应状态。概念HTTP状态码(英语:HTTPStatusCode)是用来表示网页服务器HTTP协议响应状态的三位数字代码。它由RFC2616规范定义,并得到RFC2518、RFC2817、R

    WPF WrapPanel使用与布局技巧
    WPF WrapPanel使用与布局技巧

    大家好,又见面了,我是你们的朋友全栈君。WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列,当长度或高度不够是就会自动调整进行换行,后续排序按照从上至下或从右至左的顺序进行。Orientation——根据内容自动换行。当Horizontal选项看上去类似于Windows资源管理器的缩略图视图:元素是从左向右排列的,然后自上至下自动换行。Vertical选项看上去类似于Windows资源管理器的列表视图:元素是从上向下排列的,然后从左至右自动换行。ItemHeight——所有子元素

    红队渗透测试中的文件传输方法
    红队渗透测试中的文件传输方法

    在红队渗透测试中,常常需要最大限度地利用现有环境,绕过严密防守的系统防火墙、入侵检测系统(IDS)和入侵防御系统(IPS)等监控和报警系统进行文件传输。本文将介绍多种使用操作系统自带工具进行文件传输的技巧。搭建HTTP服务器使用Python对于Python2用户:python-mSimpleHTTPServer1337

    GB28181协议是什么?是否收费?
    GB28181协议是什么?是否收费?

    在探讨GB28181协议的细节之前,让我们先了解一下与之相关的HTTP和SSDP协议的基本概念。这将帮助我们更好地理解GB28181协议的工作原理。1、HTTP协议与SSDP协议SSDP协议与HTTP协议在结构上非常相似,实际上,它们的相似之处主要在于协议内容的格式。然而,SSDP协议在使用时需要忽略端口和D类地址。当我向其他员工或面试者解释时,我总是强调深入理解HTTP协议的重要性,因为掌握了HTTP协议,理解SSDP协议就变得相对容易。许多人可能会认为HTTP协议仅仅是GET、POST、PUT、DEL

    自定义计算公式实战入门指南
    自定义计算公式实战入门指南

    本系列开启了一个全新的项目,旨在实现用户通过自定义计算公式输入一系列值(固定格式,假设为文本格式),并自动生成一系列计算后的值。这些新值将被追加到原始文本中。核心在于用户无需编程即可通过提供的UI界面操作,操作一次生成程序,以后进行同类工作无需重复操作。本项目主要涉及的模块包括traitsui和traits。Part1:目标输入:如图所示,input1.txt文本中包含一系列数值。输出:经过程序处理后,生成output1.txt,新文件是在原始文件的基础上追加了一些值,追加值的数值取决于具体的公式。这里

    如何在 Golang 中处理 HTTP 异常?
    如何在 Golang 中处理 HTTP 异常?

    如何处理HTTP异常?在Golang中,HTTP异常处理包括以下方法:自定义HTTP错误处理程序:使用http.Error自定义错误响应。内置异常处理:使用recover()恢复异常,并使用errorHandler发送错误响应。实战案例:处理无效请求:根据请求方法发送错误响应。处理服务器内部错误:使用deferrecover()捕获异常并发送错误响应。处理其他异常:通过类似的方法进行处理。

    如何使用C++实现HTTP流传输?
    如何使用C++实现HTTP流传输?

    如何在C++中实现HTTP流传输?使用Boost.Asio和asiohttps客户端库创建SSL流套接字。连接到服务器并发送HTTP请求。接收HTTP响应头并打印它们。接收HTTP响应正文并打印它。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。