retrofit-spring-boot-starter: A Lightweight HTTP Client Integration for Spring Boot
This article introduces retrofit-spring-boot-starter, a lightweight, type‑safe HTTP client starter that seamlessly integrates Retrofit into Spring Boot projects, outlines its key features, provides quick usage examples with Maven/Gradle dependencies, interface definitions, injection, configuration options, and advanced capabilities such as custom OkHttpClient injection, annotation‑based interceptors, connection‑pool management, logging, and retry mechanisms.
Introduction
Retrofit is a type‑safe HTTP client for Java and Android. Spring Boot is the most widely used Java framework, but Retrofit does not provide native Spring Boot integration. The retrofit-spring-boot-starter bridges this gap, offering a simple way to use Retrofit within Spring Boot applications.
Key Features
Custom OkHttpClient injection
Annotation‑based interceptors
Connection‑pool management
Log printing
Request retry
Error decoder
Global interceptor
Circuit‑breaker degradation
HTTP calls between micro‑services
Call adapters
Data converters
Quick Start
Dependency
<dependency>
<groupId>com.github.lianjiatech</groupId>
<artifactId>retrofit-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>Define HTTP Interface
The interface must be annotated with @RetrofitClient .
@RetrofitClient(baseUrl = "${test.baseUrl}")
public interface HttpApi {
@GET("person")
Result<Person> getPerson(@Query("id") Long id);
}Inject and Use
Inject the interface into a Spring service and call it directly.
@Service
public class TestService {
@Autowired
private HttpApi httpApi;
public void test() {
// use httpApi to send HTTP request
}
}HTTP Request Annotations
All request annotations are the native Retrofit annotations (e.g., @GET, @POST, @Query, @Body). Refer to the official Retrofit documentation for details.
Configuration Options
The starter provides many configurable properties via application.yml to adapt to different scenarios.
retrofit:
enable-response-call-adapter: true
enable-log: true
pool:
test1:
max-idle-connections: 3
keep-alive-second: 100
test2:
max-idle-connections: 5
keep-alive-second: 50
disable-void-return-type: false
logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor
retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor
global-converter-factories:
- retrofit2.converter.jackson.JacksonConverterFactory
global-call-adapter-factories:
- com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory
- com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory
enable-degrade: true
degrade-type: sentinel
resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParserAdvanced Features
Custom OkHttpClient Injection
Define a static method returning OkHttpClient.Builder and annotate it with @OkHttpClientBuilder to provide a custom client.
@RetrofitClient(baseUrl = "http://ke.com")
public interface HttpApi3 {
@OkHttpClientBuilder
static OkHttpClient.Builder okhttpClientBuilder() {
return new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(1, TimeUnit.SECONDS)
.writeTimeout(1, TimeUnit.SECONDS);
}
@GET("person")
Result<Person> getPerson(@Url String url, @Query("id") Long id);
}Annotation‑Based Interceptor
Implement BasePathMatchInterceptor and annotate the interface with @Intercept to apply interceptor logic 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);
}
}Usage example:
@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);
}Custom Intercept Annotation (@Sign)
Define a custom annotation marked with @InterceptMark that includes include() , exclude() , and handler() . The handler can add signature headers to requests.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@InterceptMark
public @interface Sign {
String accessKeyId();
String accessKeySecret();
String[] include() default {"/**"};
String[] exclude() default {};
Class
handler() default SignInterceptor.class;
}Interceptor implementation:
@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();
return chain.proceed(newReq);
}
}Apply the annotation to an interface:
@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);
}Connection‑Pool Management
Default pool settings are max-idle-connections=5 and keep-alive-second=300 . Custom pools can be defined in application.yml and selected via the poolName attribute of @RetrofitClient .
Log Printing
Global log control is via retrofit.enableLog . Per‑interface logging can be toggled with @RetrofitClient(enableLog = true) . Five log levels (ERROR, WARN, INFO, DEBUG, TRACE) and four strategies (NONE, BASIC, HEADERS, BODY) are supported.
Request Retry
Enable retry by adding @Retry on an interface or method. Configure maxRetries , intervalMs , and retryRules (e.g., RESPONSE_STATUS_NOT_2XX , OCCUR_IO_EXCEPTION , OCCUR_EXCEPTION ) in the YAML file.
retrofit:
retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptorSelected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.