Retrofit ialah alat klien HTTP selamat jenis yang sesuai untuk Android
dan Java
, yang mempunyai 39k+
Bintang di Github. Ciri terbesarnya ialah ia menyokong memulakan permintaan HTTP melalui antara muka, sama seperti cara kami menggunakan Feign untuk memanggil antara muka perkhidmatan mikro.
SpringBoot ialah rangka kerja pembangunan Java yang paling banyak digunakan, tetapi Retrofit secara rasminya tidak menyediakan Starter khusus. Jadi seorang lelaki tua telah membangunkan retrofit-spring-boot-starter
, yang merealisasikan penyepaduan pantas rangka kerja Retrofit dan SpringBoot, dan menyokong banyak peningkatan fungsi, yang sangat memudahkan pembangunan. Hari ini kami akan menggunakan Starter pihak ketiga ini untuk mengendalikan Retrofit.
Sangat mudah untuk menggunakan Retrofit dalam SpringBoot Mari kita alaminya di bawah.
Integrasi Kebergantungan
Dengan sokongan Starter pihak ketiga, penyepaduan Retrofit hanya mengambil satu langkah, cuma tambah kebergantungan berikut.
<!--Retrofit依赖--> <dependency> <groupId>com.github.lianjiatech</groupId> <artifactId>retrofit-spring-boot-starter</artifactId> <version>2.2.18</version> </dependency>
Mari kita ambil panggilan antara muka dalam mall-tiny-swagger
sebagai contoh untuk mengalami penggunaan asas Retrofit.
Mula-mula kami menyediakan perkhidmatan untuk memudahkan panggilan jauh Kami menggunakan mall-tiny-swagger
Demo Open Swagger dan lihat terdapat antara muka log masuk dan antara muka CRUD untuk jenama produk yang memerlukan pengesahan log masuk 🎜>
dalam application.yml
;
remote: baseUrl: http://localhost:8088/
mall-tiny-swagger
kemudian isytiharkan satu melalui Pelanggan Retrofit, memandangkan antara muka log masuk dipanggil melalui borang POST, anotasi dan @RetrofitClient
digunakan di sini @POST
/** * 定义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); }
@FormUrlEncoded
Jika anda tidak begitu faham untuk tujuan anotasi ini, sila lihat. di bawah Anda pada asasnya boleh memahami jadual. Untuk butiran lanjut, anda boleh merujuk kepada dokumentasi Retrofit rasmi; /** * 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; } }
Untuk memudahkan panggilan berikutnya ke antara muka yang memerlukan pengesahan log masuk, saya mencipta kelas
dan menyimpan token dalam Sesi/** * 登录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; } }
UmsAdminApi
Anotasi. PemintasTokenHolder
warisi , dan kemudian tambahkan pengepala
pada permintaan dalam kaedah/** * 给请求添加登录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); } }
, gunakan anotasi
untuk mengkonfigurasi laluan pemintas dan pemintas/** * 定义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); }
TokenInterceptor
kemudian masukkan contoh BasePathMatchInterceptor
ke dalam Pengawal dan tambah kaedah untuk memanggil perkhidmatan jauh; ; doIntercept
/** * 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); } }
Authorization
Panggil antara muka dalam Swagger untuk ujian dan mendapati ia boleh dipanggil dengan jayanya. PmsBrandApi
@Intercept
PmsBrandApi
Jika anda ingin menambah pengepala permintaan pada semua permintaan, anda boleh menggunakan pemintas global.
Buat kelas
yang mewarisi antara muka, dan kemudian tambahkan pengepala permintaan dalam Pengepala.
/** * 全局拦截器,给请求添加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); } }
SourceInterceptor
BaseGlobalInterceptor
Pencetakan log Di bawah konfigurasi lalai, Retrofit menggunakan strategi log source
dan log yang dicetak adalah sangat mudah; tambah
Retrofit menyokong empat strategi pencetakan log;retrofit: # 日志打印配置 log: # 启用日志打印 enable: true # 日志打印拦截器 logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor # 全局日志打印级别 global-log-level: info # 全局日志打印策略 global-log-strategy: bodySalin selepas log masukSelepas mengubah suai strategi pencetakan log, maklumat log lebih komprehensif; 🎜>
basic
TIADA: jangan cetak log; rekod permintaan log;
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:发生任意异常时执行重试。
Atas ialah kandungan terperinci Cara menggunakan alat klien HTTP Retrofit dalam SpringBoot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!