首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring Boot 整合 OkHttp 實現服務間 HTTP 調用

     編輯:Java 綜合教學

Spring Boot 整合 OkHttp 實現服務間 HTTP 調用

在微服務架構中,服務間同步調用常用 RestTemplate、WebClient、OkHttp、Feign。本文演示 Spring Boot 2.x 整合 OkHttp 3.x,結合 String.format() 佔位符構建動態 URL,實現簡潔的服務消費端。

架構圖解

myboot1 (消費者, port 8080)  ──HTTP GET──▶  myboot2 (提供者, port 8081)
    │                                            │
    ├─ OkHttpClient (單例 Bean)                  ├─ HotelController
    ├─ application-dev.properties (URL模板)       └─ GET /hotel/getHotelInfo?id={id}&name={name}
    └─ AddressController (調用入口)                返回 Hotel JSON

一、提供者 myboot2

1. pom.xml

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
  </dependency>
</dependencies>

2. application.properties

server.port=8081

3. 實體類

@Data @AllArgsConstructor @NoArgsConstructor
public class Hotel {
    private int id;
    private String hotelname;
}

4. Controller

@RestController
@RequestMapping("/hotel")
public class HotelController {
    @GetMapping("/getHotelInfo")
    public Hotel getHotelInfo(@RequestParam int id, @RequestParam String name) {
        return new Hotel(id, name);
    }
}

二、消費者 myboot1

1. pom.xml 新增 OkHttp

<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <version>3.14.9</version> <!-- 3.x 版本 -->
</dependency>

2. application-dev.properties (URL 模板)

service.hotel.url=https://localhost:8081/hotel/getHotelInfo?id=%d&name=%s

關鍵點:%d 對應 int,%s 對應 String,& 在 properties 中需轉義為 &amp; 或直接寫 & (YAML 無需轉義)。

3. application.properties 啟用 dev

spring.profiles.active=dev

4. OkHttpClient 配置類 (單例 Bean)

@Configuration
public class OkHttpConfig {
    @Bean
    public OkHttpClient okHttpClient() {
        return new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .build();
    }
}

5. Controller 調用邏輯

@RestController
@RequestMapping("/address")
@Slf4j
public class AddressController {
    @Value("${service.hotel.url}")
    private String hotelUrlTemplate;
    
    @Autowired
    private OkHttpClient okHttpClient;
    
    @GetMapping("/testOkHttp")
    public String testOkHttp(@RequestParam int id, @RequestParam String name) {
        String url = String.format(hotelUrlTemplate, id, name);
        log.debug("調用URL: {}", url);
        
        Request request = new Request.Builder().url(url).get().build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                log.error("調用失敗: HTTP {}", response.code());
                return "ERROR: " + response.code();
            }
            String body = response.body().string();
            log.debug("響應: {}", body);
            return body;
        } catch (IOException e) {
            log.error("調用異常", e);
            return "EXCEPTION: " + e.getMessage();
        }
    }
}

三、OkHttp 進階用法速查

場景代碼片段
POST JSONRequestBody.create(MediaType.parse("application/json"), jsonStr)
表單提交new FormBody.Builder().add("k","v").build()
文件上傳MultipartBody.Builder().addFormDataPart("file", name, RequestBody.create(MEDIA_TYPE, file)).build()
同步調用client.newCall(req).execute()
異步回調client.newCall(req).enqueue(new Callback() { onResponse/onFailure })
攔截器 (日誌/簽名).addInterceptor(chain -> { ... chain.proceed(req) ... })
連接池複用new ConnectionPool(5, 5, TimeUnit.MINUTES) 設置 OkHttpClient.Builder

四、常見問題與最佳實踐

  1. 單例模式:OkHttpClient 必須是單例,否則連接池、線程池重複創建導致資源耗盡
  2. 超時設置:生產環境務必配置連接/讀/寫超時,防止線程卡死
  3. 重試策略:retryOnConnectionFailure(true) 僅重試連接失敗,業務級重試需自行實現 (如 Resilience4j)
  4. URL 構建:推薦 HttpUrl.Builder 或 UriComponentsBuilder 替代 String.format,自動處理編碼
  5. 日誌攔截:加入 HttpLoggingInterceptor (okhttp-logging-interceptor) 打印請求響應
  6. 替代方案:Spring 官方推薦 WebClient (響應式) 或 RestClient (Spring 6.1+),Feign 適合聲明式調用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved