1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/lianjiatech-retrofit-spring-boot-starter

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README_EN.md

retrofit-spring-boot-starter

License

Build Status

Maven central

GitHub release

License

License

Author

QQ-Group

Стартер для Retrofit на Spring Boot, поддерживает быструю интеграцию и расширение функций.

  1. Для проекта Spring Boot 3.x используйте retrofit-spring-boot-starter 3.x.
  2. Для проектов Spring Boot 1.x/2.x используйте retrofit-spring-boot-starter 2.x.

Разработка с открытым исходным кодом непроста, пожалуйста, поставьте мне звезду⭐️

Функции

  • Настройка OkHttpClient
  • Перехватчик аннотаций
  • Печать логов
  • Повтор запроса
  • Снижение нагрузки
  • Декодер ошибок
  • HTTP-вызовы между микросервисами
  • Глобальный перехватчик
  • Адаптер вызова
  • Конвертер данных
  • Метааннотация
  • Другие примеры

Быстрый старт

Импорт зависимостей

<dependency>
    <groupId>com.github.lianjiatech</groupId>
   <artifactId>retrofit-spring-boot-starter</artifactId>
   <version>3.1.3</version>
</dependency>

Определение HTTP-интерфейса

Интерфейсы должны быть отмечены аннотацией @RetrofitClient! Для связанных с HTTP аннотаций см. официальную документацию: Официальная документация Retrofit.

@RetrofitClient(baseUrl = "${test.baseUrl}")
public interface UserService {

   /**
    * Запрос имени пользователя по id
    */
   @POST("getName")
   String getName(@Query("id") Long id);
}

Обратите внимание: Путь запроса метода должен начинаться с /. Для Retrofit, если baseUrl=http://localhost:8080/api/test/ и путь запроса метода равен person, то полный путь запроса метода будет: http://localhost: 8080/api/test/person. Если путь запроса метода /person, полный путь запроса метода: http://localhost:8080/person.

Использование внедрения

Внедрите интерфейс в другие сервисы для использования:

@Service
public class BusinessService {

   @Autowired
   private UserService userService;

   public void doBusiness() {
      // вызов userService
   }
}

По умолчанию Spring Boot автоматически сканирует путь для регистрации RetrofitClient. Вы также можете вручную указать путь сканирования, добавив @RetrofitScan в класс конфигурации.

Аннотации, связанные с HTTP

Все аннотации, связанные с запросами HTTP, используют собственные аннотации Retrofit. Ниже приводится краткое описание:

Классификация Поддерживаемые аннотации
Метод запроса @GET @HEAD @POST @PUT @DELETE @OPTIONS @HTTP
Заголовок запроса @Header @HeaderMap @Headers
Параметр запроса @Query Конфигурация свойств

Компонент поддерживает множество настраиваемых свойств для работы с различными бизнес-сценариями. Конкретные поддерживаемые свойства конфигурации и их значения по умолчанию следующие:

retrofit:
   global-converter-factories:
      - com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
      - retrofit2.converter.jackson.JacksonConverterFactory
   global-call-adapter-factories: 
   global-log:
      enable: true
      log-level: info
      log-strategy: basic
      aggregate: true

   global-retry:
      enable: false
      interval-ms: 100
      max-retries: 2
      retry-rules:
         - response_status_not_2xx
         - occur_io_exception

   global-timeout:
      read-timeout-ms: 10000
      write-timeout-ms: 10000
      connect-timeout-ms: 10000
      call-timeout-ms: 0
   degrade:
      degrade-type: none
      global-sentinel-degrade:
         enable: false
         # Threshold corresponding to each degrade policy. Average response time (ms), exceptions ratio (0-1), number of exceptions (1-N)
         count: 1000
         time-window: 5
         # Degradation strategy (0: average response time; 1: ratio of exceptions; 2: number of exceptions)
         grade: 0

      global-resilience4j-degrade:
         enable: false
         # Get CircuitBreakerConfig from {@link CircuitBreakerConfigRegistry} based on this name as a global circuit breaker configuration
         circuit-breaker-config-name: defaultCircuitBreakerConfig
   auto-set-prototype-scope-for-path-math-interceptor: true

Дополнительные функции

  • Настройка времени ожидания Если вам нужно изменить только время ожидания OkHttpClient, вы можете сделать это через соответствующие поля @RetrofitClient или изменить глобальную конфигурацию времени ожидания.

  • Настройте OkHttpClient Если вам необходимо изменить другую конфигурацию OkHttpClient, вы можете это сделать, настроив OkHttpClient. Шаги следующие:

  1. Реализуйте интерфейс SourceOkHttpClientRegistrar и вызовите метод SourceOkHttpClientRegistry#register() для регистрации OkHttpClient.
  2. Укажите OkHttpClient для текущего интерфейса с помощью @RetrofitClient.sourceOkHttpClient. Обратите внимание, что компонент не будет напрямую использовать указанный OkHttpClient, а создаст новый на его основе.
  • Аннотированный перехватчик Компонент предоставляет аннотированный перехват, который поддерживает перехват на основе сопоставления пути URL. Используемые шаги следующие:
  1. Наследуйте BasePathMatchInterceptor.
  2. Используйте аннотацию @Intercept, чтобы указать используемый перехватчик. Если вам нужно использовать несколько перехватчиков, вы можете пометить несколько аннотаций @Intercept на интерфейсе. Уровень журнала: информация

Стратегия ведения журнала: базовая

Агрегирование: да

Имя журнала: com.github.lianjiatech.retrofit.spring.boot.log.LoggingInterceptor

Значения четырёх стратегий печати журналов следующие:

  1. NONE: журналы не ведутся.
  2. BASIC: регистрируются строки запросов и ответов.
  3. HEADERS: регистрируются строки запросов, ответов и их соответствующие заголовки.
  4. BODY: регистрируются строки запросов, ответов, их соответствующие заголовки и тела (если они есть).

Декларативная печать журналов

Если требуется печатать журналы только для некоторых запросов, можно использовать аннотацию @Logging на соответствующем интерфейсе или методе.

Расширение настройки печати журналов

Если необходимо изменить поведение печати журналов, можно наследовать класс LoggingInterceptor и настроить его как Spring bean.

Повтор запроса

Компонентная поддержка поддерживает глобальный повтор и декларативный повтор.

Глобальный повтор

Глобальный повтор по умолчанию отключён, а элементы конфигурации по умолчанию выглядят следующим образом:

retrofit:
  global-retry:
     enable: false
     interval-ms: 100
     max-retries: 2
     retry-rules:
        - response_status_not_2xx
        - occur_io_exception

Правило повтора поддерживает три конфигурации:

  • RESPONSE_STATUS_NOT_2XX: повтор при статусе ответа, отличном от 2xx.
  • OCCUR_IO_EXCEPTION: выполнение повтора при возникновении исключения ввода-вывода.
  • OCCRU_EXCEPTION: повторение при любом исключении.

Декларативный повтор

Если только часть запроса должна быть повторена, можно использовать аннотацию @Retry на соответствующем интерфейсе или методе.

Расширение настройки повтора запроса

Если необходимо изменить поведение повтора запросов, можно наследовать RetryInterceptor и настроить его как Spring bean.

Снижение нагрузки

Снижение нагрузки по умолчанию отключено и в настоящее время поддерживает реализации sentinel и resilience4j.

retrofit:
   degrade:
      # Тип снижения нагрузки. По умолчанию — none, что означает, что снижение нагрузки не включено
      degrade-type: sentinel

Sentinel

Настройте degrade-type=sentinel для включения, а затем объявите аннотацию @SentinelDegrade на соответствующем интерфейсе или методе.

Не забудьте вручную импортировать зависимости Sentinel:

<dependency>
   <groupId>com.alibaba.csp</groupId>
   <artifactId>sentinel-core</artifactId>
   <version>1.6.3</version>
</dependency>

Кроме того, также поддерживается глобальное снижение нагрузки Sentinel:

retrofit:
  degrade:
    degrade-type: sentinel
    global-sentinel-degrade:
      enable: true
      # Другая глобальная конфигурация Sentinel

Resilience4j

Настройте degrade-type=resilience4j для включения. Затем объявите @Resilience4jDegrade на соответствующем интерфейсе или методе.

Не забудьте вручную импортировать зависимости Resilience4j:

<dependency>
   <groupId>io.github.resilience4j</groupId>
   <artifactId>resilience4j-circuitbreaker</artifactId>
   <version>1.7.1</version>
</dependency>

Также поддерживается глобальное снижение нагрузки Resilience4j:

retrofit:
   degrade:
      degrade-type: resilience4j
      global-resilience4j-degrade:
         enable: true
         # Получить CircuitBreakerConfig из {@link CircuitBreakerConfigRegistry} на основе этого имени в качестве глобальной конфигурации выключателя
         circuit-breaker-config-name: defaultCircuitBreakerConfig

Управление конфигурацией выключателя:

Реализуйте интерфейс CircuitBreakerConfigRegistrar и зарегистрируйте CircuitBreakerConfig.

@Component
public class CustomCircuitBreakerConfigRegistrar implements CircuitBreakerConfigRegistrar {
   @Override
   public void register(CircuitBreakerConfigRegistry registry) {

         registry.register(Constants.DEFAULT_CIRCUIT_BREAKER_CONFIG, CircuitBreakerConfig.ofDefaults());

         registry.register("testCircuitBreakerConfig", CircuitBreakerConfig.custom()
                 .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.TIME_BASED)
                 .failureRateThreshold(20)
                 .minimumNumberOfCalls(5) **Укажите CircuitBreakerConfig через circuitBreakerConfigName.**

Включите retrofit.degrade.global-resilience4j-degrade.circuit-breaker-config-name или @Resilience4jDegrade.circuitBreakerConfigName.

**Расширенное понижение уровня схемы.**

Если пользователю необходимо использовать другую реализацию понижения уровня схемы, наследуйте BaseRetrofitDegrade и настройте его с помощью Spring Bean.

**Настройте fallback или fallbackFactory (необязательно).**

Если @RetrofitClient не устанавливает fallback или fallbackFactory, при срабатывании прерывателя цепи будет напрямую генерироваться исключение RetrofitBlockException. Пользователи могут настроить возвращаемое значение метода при перегорании, установив fallback или fallbackFactory.

Обратите внимание: класс fallback должен быть классом реализации текущего интерфейса, а fallbackFactory должен быть FallbackFactory<T>  классом реализации универсального параметра текущего типа интерфейса. Кроме того, экземпляры fallback и fallbackFactory должны быть настроены как Spring Bean.

Основное различие между fallbackFactory и fallback заключается в том, что он может воспринимать аномальную причину (причину) каждого предохранителя. Приведённый пример:

```java
@Slf4j
@Service
public class HttpDegradeFallback implements HttpDegradeApi {

   @Override
   public Result<Integer> test() {
      Result<Integer> fallback = new Result<>();
      fallback.setCode(100)
              .setMsg("fallback")
              .setBody(1000000);
      return fallback;
   }
}
@Slf4j
@Service
public class HttpDegradeFallbackFactory implements FallbackFactory<HttpDegradeApi> {

   @Override
   public HttpDegradeApi create(Throwable cause) {
      log.error("触发熔断了! ", cause.getMessage(), cause);
      return new HttpDegradeApi() {
         @Override
         public Result<Integer> test() {
            Result<Integer> fallback = new Result<>();
            fallback.setCode(100)
                    .setMsg("fallback")
                    .setBody(1000000);
            return fallback;
         }
      };
   }
}

Декодер ошибок.

Когда в HTTP возникает ошибка запроса (включая исключение или данные ответа не соответствуют ожиданиям), декодер ошибок может декодировать информацию, связанную с HTTP, в пользовательское исключение. Вы можете использовать errorDecoder() в аннотации @RetrofitClient для указания декодера ошибок текущего интерфейса. Пользовательские декодеры ошибок должны реализовывать интерфейс ErrorDecoder:

HTTP-вызовы между микросервисами.

Наследуйте ServiceInstanceChooser.

Пользователи могут реализовать интерфейс ServiceInstanceChooser самостоятельно, завершить логику выбора экземпляров служб и настроить их как Spring Bean. Для приложения Spring Cloud это можно реализовать следующим образом:

@Service
public class SpringCloudServiceInstanceChooser implements ServiceInstanceChooser {

   private LoadBalancerClient loadBalancerClient;

   @Autowired
   public SpringCloudServiceInstanceChooser(LoadBalancerClient loadBalancerClient) {
      this.loadBalancerClient = loadBalancerClient;
   }

   /**
    * Выбирает URI ServiceInstance из LoadBalancer для указанной службы.
    *
    * @param serviceId Идентификатор службы для поиска в LoadBalancer.
    * @return Возвращает uri ServiceInstance
    */
   @Override
   public URI choose(String serviceId) {
      ServiceInstance serviceInstance = loadBalancerClient.choose(serviceId);
      Assert.notNull(serviceInstance, "can not found service instance! serviceId=" + serviceId);
      return serviceInstance.getUri();
   }
}

Укажите serviceId и path.

@RetrofitClient(serviceId = "user", path = "/api/user")
public interface ChooserOkHttpUserService {

   /**
    * 根据id查询用户信息
    */
   @GET("getUser")
   User getUser(@Query("id") Long id);
}

Глобальный перехватчик.

Если нам нужно выполнить унифицированную обработку перехвата для HTTP-запросов всей системы, мы можем реализовать глобальный перехватчик. GlobalInterceptor и настройка его как spring Bean.

@Component
public class MyGlobalInterceptor implements GlobalInterceptor {
   @Override
   public Response intercept(Chain chain) throws IOException {
      Response response = chain.proceed(chain.request());
      // response的Header加上global
      return response.newBuilder().header("global", "true").build();
   }
}

Глобальный сетевой перехватчик

Реализуйте интерфейс NetworkInterceptor и настройте его как spring Bean.

Адаптер вызовов

Retrofit может адаптировать объекты Call к типу возвращаемого значения методов интерфейса через CallAdapterFactory. Компонент расширяет некоторые реализации CallAdapterFactory:

  1. BodyCallAdapterFactory
    • Выполняет HTTP-запрос синхронно, адаптируя содержимое тела ответа к типу возвращаемого значения метода.
    • Любой тип возвращаемого значения метода может использовать BodyCallAdapterFactory, с наименьшим приоритетом.
  2. ResponseCallAdapterFactory
    • Выполняет HTTP-запрос синхронно, адаптирует содержимое тела ответа в Retrofit.Response и возвращает его.
    • ResponseCallAdapterFactory можно использовать только в том случае, если типом возвращаемого значения метода является Retrofit.Response.
  3. Связанный с реактивным программированием CallAdapterFactory, поддерживает следующие типы возвращаемых значений методов:

Retrofit выберет соответствующий CallAdapterFactory для выполнения обработки адаптации в соответствии с типом возвращаемого значения метода**. В настоящее время поддерживаются следующие типы возвращаемого значения:**

  • String: адаптирует тело ответа в строку для возврата.
  • Основные типы (Long/Integer/Boolean/Float/Double): адаптирует тело ответа к вышеуказанному основному типу.
  • Любой Java-объект: адаптирует тело ответа в соответствующий объект Java и возвращает его.
  • CompletableFuture: адаптирует тело ответа в объект CompletableFuture и возвращает его.
  • Void: Void можно использовать независимо от типа возвращаемого значения.
  • Response: Response адаптирует ответ в объект Response и возвращает его.
  • Call: обработка адаптации не выполняется, и объект Call возвращается напрямую.
  • Mono: реактивный тип возврата Project Reactor.
  • Single: реактивный тип возврата Rxjava (поддерживает Rxjava2/Rxjava3).
  • Completable: реактивный тип возврата Rxjava, HTTP-запрос не имеет тела ответа (поддерживает Rxjava2/Rxjava3).

CallAdapter можно расширить, расширив CallAdapter.Factory.

Компоненты поддерживают настройку глобальных фабрик адаптеров вызовов через retrofit.global-call-adapter-factories:

retrofit:
  # The `CallAdaptorFactory` factory extended by the component has been built in, please do not repeat the configuration here
  global-call-adapter-factories:
    # ...

Для каждого интерфейса Java также можно указать CallAdapter.Factory, используемый текущим интерфейсом, через @RetrofitClient.callAdapterFactories.

Рекомендация: настроить CallAdapter.Factory как Spring Bean.

Конвертер данных

Retrofit использует Converter для преобразования объекта, аннотированного с помощью @Body, в тело запроса, а тела ответа — в объект Java. Вы можете выбрать следующий Converter:

  • Gson: com.squareup.Retrofit:converter-gson
  • Jackson: com.squareup.Retrofit:converter-jackson
  • Moshi: com.squareup.Retrofit:converter-moshi
  • Protobuf: com.squareup.Retrofit:converter-protobuf
  • Wire: com.squareup.Retrofit:converter-wire
  • Simple XML: com.squareup.Retrofit:converter-simplexml
  • JAXB: com.squareup.retrofit2:converter-jaxb
  • fastJson:com.alibaba.fastjson.support.retrofit.Retrofit2ConverterFactory

Настройте глобальный Converter.Factory через retrofit.global-converter-factories, по умолчанию используется retrofit2.converter.jackson.JacksonConverterFactory.

Если вам нужно изменить конфигурацию Jackson, вы можете... Переопределение конфигурации компонента JacksonConverterFactory для Retrofit.

retrofit:
   global-converter-factories:
      - com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
      - retrofit2.converter.jackson.JacksonConverterFactory

Для каждого интерфейса Java вы также можете указать Converter.Factory, используемый текущим интерфейсом, с помощью @RetrofitClient.converterFactories.

Рекомендация: Настройте Converter.Factory как Spring Bean.

Метааннотация.

Аннотации, такие как @RetrofitClient, @Retry, @Logging, @Resilience4jDegrade, поддерживают метааннотации, наследование и @AliasFor.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Inherited
@RetrofitClient(baseUrl = "${test.baseUrl}")
@Logging(logLevel = LogLevel.WARN)
@Retry(intervalMs = 200)
public @interface MyRetrofitClient {

   @AliasFor(annotation = RetrofitClient.class, attribute = "converterFactories")
   Class<? extends Converter.Factory>[] converterFactories() default {GsonConverterFactory.class};

   @AliasFor(annotation = Logging.class, attribute = "logStrategy")
   LogStrategy logStrategy() default LogStrategy.BODY;
}

Другие примеры.

Параметры формы.

@FormUrlEncoded
@POST("token/verify")
 Object tokenVerify(@Field("source") String source,@Field("signature") String signature,@Field("token") String token);


@FormUrlEncoded
@POST("message")
CompletableFuture<Object> sendMessage(@FieldMap Map<String, Object> param);

Загрузка файла.

  • Создайте MultipartBody.Part
// 对文件名使用URLEncoder进行编码
public ResponseEntity importTerminology(MultipartFile file){
     String fileName=URLEncoder.encode(Objects.requireNonNull(file.getOriginalFilename()),"utf-8");
     okhttp3.RequestBody requestBody=okhttp3.RequestBody.create(MediaType.parse("multipart/form-data"),file.getBytes());
     MultipartBody.Part part=MultipartBody.Part.createFormData("file",fileName,requestBody);
     apiService.upload(part);
     return ok().build();
}
  • Интерфейс загрузки HTTP.
@POST("upload")
@Multipart
Void upload(@Part MultipartBody.Part file);

Скачивание файла.

  • Интерфейс скачивания HTTP.
@RetrofitClient(baseUrl = "https://img.ljcdn.com/hc-picture/")
public interface DownloadApi {

    @GET("{fileKey}")
    Response<ResponseBody> download(@Path("fileKey") String fileKey);
}
  • Использование скачивания HTTP.
@SpringBootTest(classes = RetrofitTestApplication.class)
@RunWith(SpringRunner.class)
public class DownloadTest {
    @Autowired
    DownloadApi downLoadApi;

    @Test
    public void download() throws Exception {
        String fileKey = "6302d742-ebc8-4649-95cf-62ccf57a1add";
        Response<ResponseBody> response = downLoadApi.download(fileKey);
        ResponseBody responseBody = response.body();
        InputStream is = responseBody.byteStream();

        File tempDirectory = new File("temp");
        if (!tempDirectory.exists()) {
            tempDirectory.mkdir();
        }
        File file = new File(tempDirectory, UUID.randomUUID().toString());
        if (!file.exists()) {
            file.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(file);
        byte[] b = new byte[1024];
        int length;
        while ((length = is.read(b)) > 0) {
            fos.write(b, 0, length);
        }
        is.close();
        fos.close();
    }
}

Динамический URL.

Используйте аннотацию @url, чтобы реализовать динамические URL. На этом этапе baseUrl можно настроить с любым допустимым URL. Например: http://github.com/ . Во время выполнения будут отправляться запросы только на основе адреса @Url.

Примечание: аннотация @url должна быть помещена в первую позицию параметра метода. Кроме того, в аннотациях, таких как @GET и @POST, нет необходимости определять путь конечной точки.

 @GET
 Map<String, Object> test3(@Url String url,@Query("name") String name);

DELETE-запрос добавляет тело запроса.

@HTTP(method = "DELETE", path = "/user/delete", hasBody = true)

GET-запрос добавляет. Сама по себе okhttp3 не поддерживает GET-запрос для добавления тела запроса. Исходный код выглядит следующим образом:

[image](https://user-images.githubusercontent.com/30620547/108949806-0a9f7780-76a0-11eb-9eb4-326d5d546e98.png)

[image](https://user-images.githubusercontent.com/30620547/108949831-1ab75700-76a0-11eb-955c-95d324084580.png) 

Автор приводит конкретные причины, вы можете обратиться к: [issue](https://github.com/square/okhttp/issues/3154).

Однако если вам действительно нужно это сделать, можно использовать: `@HTTP(method = "get", path = "/user/get", hasBody = true)`, используйте строчную букву `get`, чтобы обойти вышеуказанные ограничения.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Спринг-бут стартер для ретрофит, поддерживает быструю интеграцию и улучшение функционала. Развернуть Свернуть
Apache-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/lianjiatech-retrofit-spring-boot-starter.git
git@api.gitlife.ru:oschina-mirror/lianjiatech-retrofit-spring-boot-starter.git
oschina-mirror
lianjiatech-retrofit-spring-boot-starter
lianjiatech-retrofit-spring-boot-starter
master