本代码采用 Spring Boot 3.x + OkHttp3 + Jackson 技术栈,重点展示了如何获取印度股市列表、查询特定股票行情以及 K 线历史数据。代码遵循生产级规范,包含完整的异常处理、配置分离和详细注释。
1. 核心数据模型 (POJO)
首先定义通用的响应结构和股票行情数据模型。
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.util.List;
/**
* 通用响应包装类
*/
@Data
public class ApiResponse<T> {
private int code;
private String message;
private T data;
}
/**
* 股票行情数据模型
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class StockQuote {
private Long id; // 产品唯一标识 (PID)
private String name; // 股票名称
private String symbol; // 股票代码
private Double last; // 最新价
private Double high; // 最高价
private Double low; // 最低价
private Double chg; // 涨跌额
private Double chgPct; // 涨跌百分比
private Long time; // 时间戳
private String flag; // 国家简称 (印度为 IN)
private Integer countryId; // 国家ID (印度为 14)
}
/**
* K线数据模型
*/
@Data
public class KlineData {
private Long time;
private Double open;
private Double high;
private Double low;
private Double close;
private Long volume;
}
2. 业务服务类 (Service)
封装 OkHttp 调用逻辑,专门针对印度市场(countryId=14)进行优化。
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
@Service
public class IndiaStockService {
private final OkHttpClient httpClient;
private final ObjectMapper objectMapper;
// 配置参数
private static final String BASE_URL = "https://api.stocktv.top";
private static final String API_KEY = "您的API_KEY"; // 请联系官方获取
private static final String INDIA_COUNTRY_ID = "14"; // 印度国家标识
public IndiaStockService(OkHttpClient httpClient, ObjectMapper objectMapper) {
this.httpClient = httpClient;
this.objectMapper = objectMapper;
}
/**
* 获取印度股市列表
* @param page 页码
* @param size 每页数量
*/
public List<StockQuote> getIndiaMarketList(int page, int size) {
HttpUrl url = HttpUrl.parse(BASE_URL + "/stock/stocks").newBuilder()
.addQueryParameter("countryId", INDIA_COUNTRY_ID)
.addQueryParameter("page", String.valueOf(page))
.addQueryParameter("pageSize", String.valueOf(size))
.addQueryParameter("key", API_KEY)
.build();
return executeRequest(url, new TypeReference<ApiResponse<PaginationData<StockQuote>>>() {})
.map(res -> res.getData().getRecords())
.orElse(Collections.emptyList());
}
/**
* 获取 K 线历史数据
* @param pid 股票产品ID
* @param interval 时间周期 (PT1M, PT1H, P1D 等)
*/
public List<KlineData> getStockKline(Long pid, String interval) {
HttpUrl url = HttpUrl.parse(BASE_URL + "/stock/kline").newBuilder()
.addQueryParameter("pid", String.valueOf(pid))
.addQueryParameter("interval", interval)
.addQueryParameter("key", API_KEY)
.build();
return executeRequest(url, new TypeReference<ApiResponse<List<KlineData>>>() {})
.map(ApiResponse::getData)
.orElse(Collections.emptyList());
}
/**
* 通用 HTTP 请求执行与异常处理
*/
private <T> java.util.Optional<T> executeRequest(HttpUrl url, TypeReference<T> typeReference) {
Request request = new Request.Builder().url(url).get().build();
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful() || response.body() == null) {
// 此处应接入日志系统记录错误
return java.util.Optional.empty();
}
String body = response.body().string();
return java.util.Optional.ofNullable(objectMapper.readValue(body, typeReference));
} catch (IOException e) {
// 异常处理逻辑,如重试或报警
e.printStackTrace();
return java.util.Optional.empty();
}
}
}
3. 技术要点说明
- 参数规范化:针对印度市场,代码中硬编码了
countryId = 14,确保所有请求均精准定位到印度证券交易所(NSE/BSE)的数据。 - 资源管理:使用 Java 7+ 的
try-with-resources确保Response对象在使用完毕后及时关闭,防止 Socket 连接泄漏。 - 健壮性:
- 引入
Jackson的@JsonIgnoreProperties(ignoreUnknown = true),避免 API 升级增加新字段时导致反序列化崩溃。 - 通过
ApiResponse<T>统一处理 API 的业务状态码(code: 200)。
- 可扩展性:提供了通用的
executeRequest私有方法,方便后续快速增加“涨跌榜”、“IPO日历”等新接口的对接。
4. 快速运行建议
- 依赖:在
pom.xml中添加okhttp(4.x),jackson-databind, 和lombok。 - Key 获取:必须联系 API 提供方获取有效的
key,否则请求将返回认证失败。 - 频率限制:生产环境下建议对调用增加速率限制(Rate Limiting),并针对行情数据增加本地缓存(如 Redis),以减少 API 消耗和提升响应速度。