Using OKHTTP, httpClient or RestTemplate to initiate HTTP requests in SpringBoot projects is cumbersome and inconvenient for unified management. Therefore, retrofit-Spring-boot-Starter, a lightweight HTTP client framework for SpringBoot projects, is recommended here. It is very simple to use and provides many enhancements. At present, the project has been updated to version 2.2.2 and will continue to be optimized iteratively.

Github project address: github.com/LianjiaTech…

Gitee Project address: gitee.com/lianjiatech…

preface

Retrofit is a type-safe HTTP client for Android and Java. The biggest feature of Retrofit is its support for making HTTP requests via an interface. Spring-boot is the most widely used Java development framework, but Retrofit does not officially support fast integration with the Spring-Boot framework, so we developed Retrofit-Spring-boot-Starter.

Retrofit-spring-boot-starter enables quick integration of Retrofit into the Spring-boot framework and supports a number of enhancements that greatly simplify development.

πŸš€ project continues to optimize and iterate, welcome to ISSUE and PR! Please give us a star✨, your star is the power of our continuous update!

features

  • Custom injection OkHttpClient
  • Annotated interceptors
  • Connection Pool Management
  • Log print
  • Request retry
  • Error decoder
  • Global interceptor
  • Fusing the drop
  • HTTP calls between microservices
  • Call adapter
  • Data converter

Quick to use

Introduction of depend on

<dependency>
    <groupId>com.github.lianjiatech</groupId>
    <artifactId>retrofit-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
Copy the code

Defining an HTTP interface

Interfaces must be marked with @RetrofitClient annotations! For HTTP notes refer to the official documentation: Retrofit official documentation.

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

    @GET("person")
    Result<Person> getPerson(@Query("id") Long id);
}
Copy the code

Injection use

Inject the interface into another Service and use it!

@Service
public class TestService {

    @Autowired
    private HttpApi httpApi;

    public void test(a) {
        // Initiate an HTTP request using httpApi}}Copy the code

Notes related to HTTP requests

HTTP request related annotations, all using Retrofit native annotations. Refer to the official documentation for details: Retrofit’s official documentation. Here is a brief explanation.

Annotations classification Supporting notes
Request way @GET @HEAD @POST @PUT @DELETE @OPTIONS
Request header @Header @HeaderMap @Headers
The Query parameter @Query @QueryMap @QueryName
The path parameter @Path
Form – encoded parameters @Field @FieldMap @FormUrlEncoded
File upload @Multipart @Part @PartMap
The url parameter @Url

Configuration Item Description

Retrofit-spring-boot-starter supports several configurable properties for different business scenarios. You can modify as required. The details are as follows:

configuration The default value instructions
enable-log true Enabling Log Printing
logging-interceptor DefaultLoggingInterceptor Log print interceptor
pool Connection Pool Configuration
disable-void-return-type false Disable the java.lang.Void return type
retry-interceptor DefaultRetryInterceptor Request a retry interceptor
global-converter-factories JacksonConverterFactory Global converter factory
global-call-adapter-factories BodyCallAdapterFactory,ResponseCallAdapterFactory Call the adapter factory globally
enable-degrade false Whether to enable fuse downgrading
degrade-type sentinel Implementation mode of fuse downgrading (currently only Sentinel is supported)
resource-name-parser DefaultResourceNameParser Fuse resource name resolver, used to resolve resource names

Yml configuration mode:

retrofit:
  enable-response-call-adapter: true
  # Enable log printing
  enable-log: true
  Connection pool configuration
  pool:
    test1:
      max-idle-connections: 3
      keep-alive-second: 100
    test2:
      max-idle-connections: 5
      keep-alive-second: 50
  # disable the void return value type
  disable-void-return-type: false
  # log print interceptor
  logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor
  Request retry interceptor
  retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor
  # Global converter factory
  global-converter-factories:
    - retrofit2.converter.jackson.JacksonConverterFactory
  Call the adapter factory globally
  global-call-adapter-factories:
    - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory
    - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory
  Whether to enable fuse downgrading
  enable-degrade: true
  # Implementation of fuse downgrading
  degrade-type: sentinel
  # fuses the resource name resolver
  resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser
Copy the code

Advanced features

Custom injection OkHttpClient

In general, the dynamic creation of OkHttpClient objects via the @RetrofitClient annotation attribute is sufficient for most usage scenarios. However, in some cases, users may need to customize OkHttpClient. In this case, static methods of type okHttpClient.Builder can be defined on the interface. A code example is as follows:

@RetrofitClient(baseUrl = "http://ke.com")
public interface HttpApi3 {

    @OkHttpClientBuilder
    static OkHttpClient.Builder okhttpClientBuilder(a) {
        return new OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.SECONDS)
                .readTimeout(1, TimeUnit.SECONDS)
                .writeTimeout(1, TimeUnit.SECONDS);

    }

    @GET
    Result<Person> getPerson(@Url String url, @Query("id") Long id);
}
Copy the code

Methods must be marked with the @okHttpClientBuilder annotation!

Annotated interceptors

Many times, we want to perform uniform interception processing logic for some HTTP requests under an interface. To support this functionality, Retrofit-spring-boot-starter provides annotated interceptors that match intercepts based on URL paths. The steps are mainly divided into two steps:

  1. inheritanceBasePathMatchInterceptorWrite interception handlers;
  2. Use on the interface@InterceptAnnotate. If multiple interceptors are required, mark them on the interface@InterceptNotes!

The following uses the annotated interceptor as an example to concatenate a TIMESTAMP after a specified request URL.

inheritanceBasePathMatchInterceptorWrite interception handler

@Component
public class TimeStampInterceptor extends BasePathMatchInterceptor {

    @Override
    public Response doIntercept(Chain chain) throws IOException {
        Request request = chain.request();
        HttpUrl url = request.url();
        long timestamp = System.currentTimeMillis();
        HttpUrl newUrl = url.newBuilder()
                .addQueryParameter("timestamp", String.valueOf(timestamp))
                .build();
        Request newRequest = request.newBuilder()
                .url(newUrl)
                .build();
        returnchain.proceed(newRequest); }}Copy the code

Use on the interface@InterceptLabeled with

@RetrofitClient(baseUrl = "${test.baseUrl}")
@Intercept(handler = TimeStampInterceptor.class, include = {"/api/**"}, exclude = "/api/test/savePerson")
public interface HttpApi {

    @GET("person")
    Result<Person> getPerson(@Query("id") Long id);

    @POST("savePerson")
    Result<Person> savePerson(@Body Person person);
}
Copy the code

The @Intercept configuration says: Intercept requests from HttpApi/API /** paths (excluding/API /test/savePerson) using TimeStampInterceptor.

Extend annotated interceptors

Sometimes, we need to pass in arguments dynamically in intercepting annotations, and then we need to use this argument in intercepting annotations. In such cases, we can extend the implementation of custom intercepting annotations. Custom InterceptMark annotations must use the @interceptmark tag and include include(), exclude(), and handler() attributes. The steps are mainly divided into three steps:

  1. Custom interception annotations
  2. inheritanceBasePathMatchInterceptorWrite interception handler
  3. Using custom intercepting annotations on interfaces

For example, we need to dynamically add accessKeyId and accessKeySecret signature information in the request header to initiate HTTP requests normally. In this case, we can define a signature interceptor annotation @sign to achieve this. The following uses custom @Sign interception annotations as an example.

The custom@Signannotations

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@InterceptMark
public @interface Sign {
    /** * Key * Supports placeholder configuration. * *@return* /
    String accessKeyId(a);

    /** * key * supports placeholder configuration. * *@return* /
    String accessKeySecret(a);

    /** * Interceptor matches path **@return* /
    String[] include() default {"/ * *"};

    /** * interceptors exclude matches, exclude the specified path interceptor **@return* /
    String[] exclude() default {};

    /** * The interceptor class that handles this annotation * gets the corresponding Bean from the Spring container first, or creates one using reflection if it doesn't! * *@return* /
    Class<? extends BasePathMatchInterceptor> handler() default SignInterceptor.class;
}
Copy the code

There are two things to note about extending custom interceptor annotations:

  1. Custom interception annotationsYou must use the@InterceptMarkThe tag.
  2. This must be included in the annotationsInclude (), exclude(), handler()Attribute information.

implementationSignInterceptor

@Component
public class SignInterceptor extends BasePathMatchInterceptor {

    private String accessKeyId;

    private String accessKeySecret;

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    @Override
    public Response doIntercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request newReq = request.newBuilder()
                .addHeader("accessKeyId", accessKeyId)
                .addHeader("accessKeySecret", accessKeySecret)
                .build();
        returnchain.proceed(newReq); }}Copy the code

The above accessKeyId and accessKeySecret fields are automatically injected based on the accessKeyId() and accessKeySecret() values of the @Sign annotation, or the configuration property value if @Sign specifies a placeholder string. In addition, the accessKeyId and accessKeySecret fields must provide setter methods.

Use on the interface@Sign

@RetrofitClient(baseUrl = "${test.baseUrl}")
@Sign(accessKeyId = "${test.accessKeyId}", accessKeySecret = "${test.accessKeySecret}", exclude = {"/api/test/person"})
public interface HttpApi {

    @GET("person")
    Result<Person> getPerson(@Query("id") Long id);

    @POST("savePerson")
    Result<Person> savePerson(@Body Person person);
}
Copy the code

This will automatically add the signature information to the request for the specified URL.

Connection Pool Management

By default, all HTTP requests sent over Retrofit will use the default connection pool of max-idle-connections=5 keep-alive-second=300. Of course, it is also possible to configure multiple custom connection pools in a configuration file and specify their use via the poolName attribute of @RetrofitClient. PoolName =test1; poolName=test1; poolName=test1;

  1. Configure the connection pool.

    retrofit:
        Connection pool configuration
        pool:
            test1:
            max-idle-connections: 3
            keep-alive-second: 100
            test2:
            max-idle-connections: 5
            keep-alive-second: 50
    Copy the code
  2. The poolName attribute of @RetrofitClient specifies the connection pool to use.

    @RetrofitClient(baseUrl = "${test.baseUrl}", poolName="test1")
    public interface HttpApi {
    
        @GET("person")
        Result<Person> getPerson(@Query("id") Long id);
    }
    Copy the code

Log print

In many cases, we want to log HTTP requests. You can configure retrofit.enableLog to control whether logs are enabled globally. For each interface, you can use the enableLog function of @RetrofitClient to control whether the function is enabled. You can specify the log printing level and log printing policy of each interface based on logLevel and logStrategy. Retrofit-spring-boot-starter supports five log printing levels (ERROR, WARN, INFO, DEBUG, TRACE), the default INFO; Four log printing policies (NONE, BASIC, HEADERS, BODY) are supported. The default is BASIC. The meanings of the four log printing policies are as follows:

  1. NONE: No logs.
  2. BASIC: Logs Request and response lines.
  3. HEADERSLogs request and response lines and their respective headers.
  4. BODY: Logs Request and response lines and their respective headers and bodies (if present).

Retrofit – spring – the boot – starter default to the execution DefaultLoggingInterceptor real log printing function, its underlying is HttpLoggingInterceptor okhttp native. Of course, you can also realize your log custom print interceptors, only needs to inherit BaseLoggingInterceptor specific can consult DefaultLoggingInterceptor (implementation), then in the configuration file for the related configuration.

retrofit:
  # log print interceptor
  logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor
Copy the code

Request retry

Retrofit-spring-boot-starter supports request Retry by annotating the @retry annotation on the interface or method. @retry Indicates the maximum number of retries, intervalMs, and retryRules. The retry rule supports three configurations:

  1. RESPONSE_STATUS_NOT_2XX: The response status code is not2xxTo retry.
  2. OCCUR_IO_EXCEPTIONRetry when AN I/O exception occurs.
  3. OCCUR_EXCEPTION: Retry when any exception occurs.

The default response status code is not 2XX or the system automatically retries when I/O exceptions occur. If necessary, you can also inherit the BaseRetryInterceptor and implement your own request retry interceptor, and then configure it.

retrofit:
  Request retry interceptor
  retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor
Copy the code

Error decoder

When an HTTP request error occurs (including an exception or the response data does not meet expectations), the error decoder decodes HTTP information into a custom exception. You can specify the errorDecoder for the current interface in the errorDecoder() annotation @retrofitclient. Custom error decoders need to implement the errorDecoder interface:

/** * error decoder. ErrorDecoder. * Decodes HTTP information into the exception when an exception occurs or an invalid response result is received. * * When an exception occurs in the request or an invalid response result is received, the HTTP related information is decoded into the exception, * and the invalid response is determined by the business itself. * *@authorChen tian Ming * /
public interface ErrorDecoder {

    /** * When an invalid response occurs, the HTTP message is decoded into an exception, and the invalid response is determined by the business itself. * When the response is invalid, decode the HTTP information into the exception, invalid response is determined by business. * *@param request  request
     * @param response response
     * @return If it returns null, the processing is ignored and the processing continues with the original response.
     */
    default RuntimeException invalidRespDecode(Request request, Response response) {
        if(! response.isSuccessful()) {throw RetrofitException.errorStatus(request, response);
        }
        return null;
    }


    /** * Decodes HTTP information into an EXCEPTION when an IO exception occurs on the request. * When an IO exception occurs in the request, the HTTP information is decoded into the exception. * *@param request request
     * @param cause   IOException
     * @return RuntimeException
     */
    default RuntimeException ioExceptionDecode(Request request, IOException cause) {
        return RetrofitException.errorExecuting(request, cause);
    }

    /** * Decodes the HTTP message into the exception when the request encounters an exception other than the IO exception. * When the request has an exception other than the IO exception, the HTTP information is decoded into the exception. * *@param request request
     * @param cause   Exception
     * @return RuntimeException
     */
    default RuntimeException exceptionDecode(Request request, Exception cause) {
        returnRetrofitException.errorUnknown(request, cause); }}Copy the code

Global interceptor

Apply interceptors globally

If we need to implement a unified interceptor for HTTP requests throughout the system, we can customize the BaseGlobalInterceptor and configure it as a Bean in the Spring container. For example, HTTP requests that we need to make across the entire system are made with source information.

@Component
public class SourceInterceptor extends BaseGlobalInterceptor {
    @Override
    public Response doIntercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request newReq = request.newBuilder()
                .addHeader("source"."test")
                .build();
        returnchain.proceed(newReq); }}Copy the code

Global Network interceptor

Simply implement the NetworkInterceptor interface and configure beans in the spring container to support automatic weaving into the global NetworkInterceptor.

Fusing the drop

In distributed service architecture, fuse downgrading of unstable external services is one of the important measures to ensure high availability of services. Since the stability of the external service is not guaranteed, when the external service is unstable, the response time becomes longer. Accordingly, callers’ response times become longer, threads pile up, and the caller’s thread pool may eventually be exhausted, making the entire service unavailable. Therefore, we need to fuse down unstable weak dependent service calls to temporarily cut off unstable calls to avoid local instability resulting in an overall service avalanche.

Retrofit-spring-boot-starter supports fuse downgrading, with the underlying implementation based on Sentinel. Specifically, it supports fusing resource self-discovery and annotated degradation rule configuration. To use circuit breaker downgrade, you only need to perform the following operations:

1. Enable the fuse degrade function

By default, the circuit breaker degrade function is disabled. You need to set the corresponding configuration items to enable the circuit breaker degrade function:

retrofit:
  Whether to enable fuse downgrading
  enable-degrade: true
  # Fusible downgrade implementation mode (currently only supported by Sentinel)
  degrade-type: sentinel
  # resource name resolver
  resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser
Copy the code

Resource name resolution is used to implement custom resource name, the default configuration is DefaultResourceNameParser, corresponding resource name format for HTTP_OUT: GET: http://localhost:8080/api/degrade/test. Users can inherit the BaseResourceNameParser class to implement their own resource name parser.

In addition, since the fusible degrade function is optional, enabling fusible degrade requires users to introduce Sentinel dependencies themselves:

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

2. (Optional) Configure degradation rules.

Retrofit-spring-boot-starter supports annotated Degrade rules. Degrade rules are configured using the @degrade annotation. The @degrade annotation can be configured on interfaces or methods, and takes precedence over methods.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface Degrade {

    /** * RT threshold or exception ratio threshold count. */
    double count(a);

    /** * Degrade recover timeout (in seconds) when degradation occurs. */
    int timeWindow(a) default 5;

    /** * Degrade strategy (0: average RT, 1: exception ratio). */
    DegradeStrategy degradeStrategy(a) default DegradeStrategy.AVERAGE_RT;
}
Copy the code

If the application project supports configuring degrade rules through the configuration center, you can ignore the annotated configuration.

3. @retrofitClient set fallback or fallbackFactory (optional)

If @RetrofitClient does not set fallback or fallbackFactory, a RetrofitBlockException will be thrown directly when a fuse is triggered. You can customize the method return value for fusing by setting fallback or fallbackFactory. Fallback class must be the implementation class of the current interface, fallbackFactory must be the implementation class of fallbackFactory

, and the generic parameter type must be the current interface type. In addition, fallback and fallbackFactory instances must be configured as Beans of the Spring container.

The main difference between fallbackFactory and Fallback is that fallbackFactory can sense the abnormal cause of each fuse break. The following is an example:

@Slf4j
@Service
public class HttpDegradeFallback implements HttpDegradeApi {

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

    /**
     * Returns an instance of the fallback appropriate for the given cause
     *
     * @param cause fallback cause
     * @returnAn instance that implements the Retrofit interface. an instance that implements the retrofit interface. */
    @Override
    public HttpDegradeApi create(Throwable cause) {
        log.error("Trigger fuse! ", cause.getMessage(), cause);
        return new HttpDegradeApi() {
            @Override
            public Result<Integer> test(a) {
                Result<Integer> fallback = new Result<>();
                fallback.setCode(100)
                        .setMsg("fallback")
                        .setBody(1000000);
                returnfallback; }}}Copy the code

HTTP calls between microservices

In order to be able to use microservice invocations, the following configuration is required:

configurationServiceInstanceChooserforSpringThe containerBean

You can implement the ServiceInstanceChooser interface, complete the service instance selection logic, and configure it as a Spring container Bean. For Spring Cloud applications, retrofit – Spring – the boot – the starter provides SpringCloudServiceInstanceChooser implementation, users only need to configure it into Spring beans.

@Bean
@Autowired
public ServiceInstanceChooser serviceInstanceChooser(LoadBalancerClient loadBalancerClient) {
    return new SpringCloudServiceInstanceChooser(loadBalancerClient);
}
Copy the code

use@RetrofittheserviceIdandpathProperty to implement HTTP calls between microservices

@RetrofitClient(serviceId = "${jy-helicarrier-api.serviceId}", path = "/m/count", errorDecoder = HelicarrierErrorDecoder.class)
@Retry
public interface ApiCountService {}Copy the code

Invoke the adapter and data transcoder

Call adapter

Retrofit can adapt a Call

object to the return value type of an interface method by calling the adapter CallAdapterFactory. Retrofit-spring-boot-starter extends 2 CallAdapterFactory implementations:

  1. BodyCallAdapterFactory
    • This function is enabled by default and can be configuredretrofit.enable-body-call-adapter=falseShut down
    • Synchronously executes the HTTP request, matching the response body content to an instance of the return value type of the interface method.
    • In addition toRetrofit.Call<T>,Retrofit.Response<T>,java.util.concurrent.CompletableFuture<T>Other return types can use this adapter.
  2. ResponseCallAdapterFactory
    • This function is enabled by default and can be configuredretrofit.enable-response-call-adapter=falseShut down
    • Synchronously executes the HTTP request and ADAPTS the response body content toRetrofit.Response<T>To return.
    • If the method returns a value of typeRetrofit.Response<T>, the adapter can be used.

Retrofit automatically selects the corresponding value based on the method return value typeCallAdapterFactoryPerform adaptation processing! Plus Retrofit by defaultCallAdapterFactory, can support many forms of method return value types:

  • Call<T>: Returns directly without adaptation processingCall<T>object
  • CompletableFuture<T>: ADAPTS the response body content toCompletableFuture<T>The object returned
  • Void: Can be used regardless of the return typeVoid. If the HTTP status code is not 2xx, throw an error!
  • Response<T>: ADAPTS the response content toResponse<T>The object returned
  • Any other Java type: return the response body to a corresponding Java type object. If the HTTP status code is not 2xx, throw an error!
    /** * Call<T> * Returns the Call<T> object * without performing adaptation@param id
     * @return* /
    @GET("person")
    Call<Result<Person>> getPersonCall(@Query("id") Long id);

    /** * CompletableFuture<T> * Matching the response body content to the CompletableFuture<T> object returns *@param id
     * @return* /
    @GET("person")
    CompletableFuture<Result<Person>> getPersonCompletableFuture(@Query("id") Long id);

    /** * Void * Regardless of the return type, you can use Void. If the HTTP status code is not 2xx, throw an error! *@param id
     * @return* /
    @GET("person")
    Void getPersonVoid(@Query("id") Long id);

    /** * Response<T> * ADAPTS the Response content to the Response<T> object returns *@param id
     * @return* /
    @GET("person")
    Response<Result<Person>> getPersonResponse(@Query("id") Long id);

    /** * If the HTTP status code is not 2xx, throw an error. *@param id
     * @return* /
    @GET("person")
    Result<Person> getPerson(@Query("id") Long id);

Copy the code

We can also implement our own CallAdapter by inheriting the CallAdapter.factory extension!

Retrofit-spring-boot-starter supports configuring the adapter factory globally with retrofit.global-Call-Adapter-Factories. The factory instance is first fetched from the Spring container, and if not, it is created by reflection. The default global call adapter factory is [BodyCallAdapterFactory ResponseCallAdapterFactory]!

retrofit:
  Call the adapter factory globally
  global-call-adapter-factories:
    - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory
    - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory
Copy the code

For each Java interface, you can also specify the callAdapterfactory used by the current interface with callAdapterFactories() annotated with @RetrofitClient, and the specified Factory instance is still preferfully retrieved from the Spring container.

Note: If the callAdapter. Factory does not have a public no-argument constructor, manually configure it as a Spring container Bean object!

Data transcoder

Retrofit uses Converter to convert the object annotated by the @Body annotation into the request Body and the response Body data into a Java object. There are several options for Retrofit:

  • 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

Retrofit-spring-boot-starter supports configuring global data converter factories with Retrofit.global-Converter-Factories. The converter factory instance is first fetched from the Spring container, and if not, it is created by reflection. The default global data converter factory is retrofit2 converter. Jackson. JacksonConverterFactory, you can directly through the spring. Jackson. * configuration Jackson serialization rules, For the configuration, see Customize the Jackson ObjectMapper!

retrofit:
  # Global converter factory
  global-converter-factories:
    - retrofit2.converter.jackson.JacksonConverterFactory
Copy the code

For each Java interface, you can also specify the converterFactories() used by the current interface with the @RetrofitClient annotations, and the specified Converter Factory instance is still preferfully retrieved from the Spring container.

Note: If Converter.Factory does not have a public no-argument constructor, manually configure it as a Spring container Bean object!

conclusion

Retrofit-spring-boot-starter, a lightweight HTTP client framework for SpringBoot projects, has been up and running for over a year and has been used by several outside companies. Interested friends can try, if you have any questions, welcome to issue or add QQ group (806714302) feedback, rapid response support.

Original is not easy, feel that the article is written well small partners, a praise πŸ‘ to encourage it ~

Welcome to my open source project: a lightweight HTTP invocation framework for SpringBoot