Integrating Retrofit with Spring Boot Using retrofit‑spring‑boot‑starter

This article explains how to replace direct OkHttp or RestTemplate usage in Spring Boot projects with the retrofit‑spring‑boot‑starter, covering dependency setup, annotation configuration, interface definition, injection, custom interceptors, connection‑pool management, logging, exception formatting, call adapters, converters, and global interceptors.

Top Architect
Top Architect
Top Architect
Integrating Retrofit with Spring Boot Using retrofit‑spring‑boot‑starter

OkHttp is a popular Java HTTP client open‑sourced by Square, and Retrofit builds on top of it to provide a declarative interface for HTTP calls. For Spring Boot projects still using RestTemplate or raw OkHttp, the retrofit‑spring‑boot‑starter offers a quick integration.

Dependency Introduction

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

Configuring @RetrofitScan

Apply @RetrofitScan on a @Configuration class or directly on the Spring Boot main class to enable scanning of Retrofit interfaces.

@SpringBootApplication
@RetrofitScan("com.github.lianjiatech.retrofit.spring.boot.test")
public class RetrofitTestApplication {
    public static void main(String[] args) {
        SpringApplication.run(RetrofitTestApplication.class, args);
    }
}

Defining HTTP Interfaces

Mark interfaces with @RetrofitClient. Example:

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

Injecting and Using the Interface

@Service
public class TestService {
    @Autowired
    private HttpApi httpApi;
    public void test() {
        // invoke httpApi methods
    }
}

Annotation‑Based Interceptor

Implement a class extending BasePathMatchInterceptor and annotate the interface method with @Intercept to apply it to specific URL patterns.

@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();
        return chain.proceed(newRequest);
    }
}
@RetrofitClient(baseUrl = "${test.baseUrl}")
@Intercept(handler = TimeStampInterceptor.class, include = {"/api/**"}, exclude = "/api/test/savePerson")
public interface HttpApi { ... }

Custom @Sign Annotation

Create a custom annotation marked with @InterceptMark that carries access‑key parameters, then implement a corresponding interceptor to add these headers.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@InterceptMark
public @interface Sign {
    String accessKeyId();
    String accessKeySecret();
    String[] include() default {"/**"};
    String[] exclude() default {};
    Class<? extends BasePathMatchInterceptor> handler() default SignInterceptor.class;
}
@Component
public class SignInterceptor extends BasePathMatchInterceptor {
    private String accessKeyId;
    private String accessKeySecret;
    public void setAccessKeyId(String id) { this.accessKeyId = id; }
    public void setAccessKeySecret(String secret) { this.accessKeySecret = secret; }
    @Override
    public Response doIntercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request newReq = request.newBuilder()
            .addHeader("accessKeyId", accessKeyId)
            .addHeader("accessKeySecret", accessKeySecret)
            .build();
        return chain.proceed(newReq);
    }
}

Connection‑Pool Management

Default pool: max-idle-connections=5 keep-alive-second=300. Custom pools can be defined in application.yml and selected via @RetrofitClient(poolName="test1").

retrofit:
  pool:
    test1:
      max-idle-connections: 3
      keep-alive-second: 100
    test2:
      max-idle-connections: 5
      keep-alive-second: 50

Logging

Five log levels (ERROR, WARN, INFO, DEBUG, TRACE) and four strategies (NONE, BASIC, HEADERS, BODY) are supported via logLevel and logStrategy on @RetrofitClient. The starter uses DefaultLoggingInterceptor under the hood.

HTTP Exception Formatter

Customize exception messages by implementing BaseHttpExceptionMessageFormatter and configuring it as a bean.

CallAdapter Support

The starter provides BodyCallAdapterFactory and ResponseCallAdapterFactory to adapt Call<T>, CompletableFuture<T>, Response<T>, Void, and arbitrary Java types.

Converter Options

Supported converters include Gson, Jackson, Moshi, Protobuf, Wire, and Simple XML. Jackson is the default; other converters can be added by providing the appropriate Converter.Factory bean.

Global Interceptor

Implement BaseGlobalInterceptor to apply headers or other logic to every HTTP request.

@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();
        return chain.proceed(newReq);
    }
}

Conclusion

The retrofit‑spring‑boot‑starter offers a concise, annotation‑driven way to perform HTTP calls in Spring Boot, with extensible interceptors, logging, connection‑pool control, and flexible converters, making it a powerful alternative to RestTemplate.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaConfigurationSpring BootInterceptorRetrofitHTTP client
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.