Master Retrofit in Spring Boot: Seamless HTTP Calls with Minimal Code
This tutorial walks through integrating the Retrofit HTTP client into Spring Boot using the retrofit‑spring‑boot‑starter, covering dependency setup, interface definition, token handling, global interceptors, and essential configuration such as logging, timeouts, and retry policies.
Introduction
Retrofit is a type‑safe HTTP client framework for Android and Java that lets you declare interfaces to make HTTP requests, avoiding repetitive connection and response parsing code. It has over 43k stars on GitHub.
The official Retrofit project does not provide a Spring Boot starter, so the community created retrofit-spring-boot-starter to integrate Retrofit quickly with Spring Boot and add many enhancements.
Usage
Using Retrofit in a Spring Boot project is straightforward; the following steps demonstrate the process.
Dependency Integration
Add the starter dependency to your pom.xml:
<!-- Retrofit related dependency -->
<dependency>
<groupId>com.github.lianjiatech</groupId>
<artifactId>retrofit-spring-boot-starter</artifactId>
<version>${retrofit-start.version}</version>
</dependency>Basic Usage
We will call the login and brand management APIs of the mall e‑commerce project as an example.
The mall project is a Spring Boot 3 + Vue e‑commerce system (GitHub ★60K) that supports a full order workflow.
Boot project: https://github.com/macrozheng/mall
Cloud project: https://github.com/macrozheng/mall-swarm
Tutorial site: https://www.macrozheng.com
First, start the mall-admin service and configure its base URL in application.yml:
remote:
baseUrl: http://localhost:8080/Define a Retrofit client interface for the admin service:
@RetrofitClient(baseUrl = "${remote.baseUrl}")
public interface UmsAdminApi {
@POST("admin/login")
CommonResult<LoginResult> login(@Body LoginParam loginParam);
}Inject the client into a controller and call the remote login API:
@RestController
@RequestMapping("/retrofit")
public class RetrofitController {
@Autowired
private UmsAdminApi umsAdminApi;
@Autowired
private TokenHolder tokenHolder;
@PostMapping("/admin/login")
public CommonResult<LoginResult> login(@RequestParam String username,
@RequestParam String password) {
CommonResult<LoginResult> result = umsAdminApi.login(new LoginParam(username, password));
if (result.getData() != null) {
tokenHolder.putToken(result.getData().getTokenHead() + " " + result.getData().getToken());
}
return result;
}
}Store the token in the HTTP session with a simple helper class:
@Component
public class TokenHolder {
public void putToken(String token) {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
request.getSession().setAttribute("token", token);
}
public String getToken() {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
Object token = request.getSession().getAttribute("token");
return token != null ? (String) token : null;
}
}Create an annotation‑based interceptor to add the token to brand‑related requests:
@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);
}
}Define the brand API with the interceptor applied:
@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);
}Inject PmsBrandApi into a controller and expose CRUD endpoints that delegate to the remote service.
@RestController
@RequestMapping("/retrofit")
public class RetrofitController {
@Autowired
private PmsBrandApi pmsBrandApi;
@GetMapping("/brand/list")
public CommonResult<CommonPage<PmsBrand>> listBrand(@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "3") Integer pageSize) {
return pmsBrandApi.list(pageNum, pageSize);
}
// other CRUD methods omitted for brevity
}For a global request header, implement a global interceptor:
@Component
public class SourceInterceptor implements GlobalInterceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request newReq = request.newBuilder()
.addHeader("source", "retrofit")
.build();
return chain.proceed(newReq);
}
}Configuration
Retrofit offers several common configuration options such as logging, timeout, and retry.
Logging
Set retrofit.global-log.log-strategy to body for full request/response logs.
retrofit:
global-log:
enable: true
log-level: info
log-strategy: bodyGlobal Timeout
retrofit:
global-timeout:
connect-timeout-ms: 3000
read-timeout-ms: 3000
write-timeout-ms: 35000
call-timeout-ms: 0Global Retry
retrofit:
global-retry:
enable: true
interval-ms: 100
max-retries: 2
retry-rules:
- response_status_not_2xx
- occur_exceptionConclusion
Retrofit provides an elegant way to make HTTP calls in Spring Boot applications, offering features beyond the traditional Feign approach, including support for microservice calls and circuit‑breaker capabilities.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.
