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

Java 調用星座運勢 HTTP API 完整範例:聚合數據接口整合

     編輯:Java 相關知識

接口規格

  • 提供方:聚合數據
  • 接口地址:https://web.juhe.cn:8080/constellation/getAll
  • 請求方式:GET/POST
  • 參數:key(AppKey)、consName(星座名)、type(today/tomorrow/week/month/year)
  • 返回:JSON,含 error_code (0 成功)、result 對象

完整工具類(原生 HttpURLConnection,零依賴)

public class JuheConstellationClient {
    private static final String API_URL = "https://web.juhe.cn:8080/constellation/getAll";
    private static final String APP_KEY = "YOUR_APP_KEY_HERE"; // 替換為你的 Key
    private static final int CONNECT_TIMEOUT = 5000;
    private static final int READ_TIMEOUT = 10000;
    private static final String USER_AGENT = "Mozilla/5.0 (Java HttpClient)";

    public record ConstellationResult(
        String name, String datetime, String overall, String love,
        String career, String money, String health, String luckyColor,
        String luckyNumber, String QFriend, String summary
    ) {}

    public ConstellationResult getFortune(String consName, String type) 
            throws IOException, InterruptedException {
        // 構建查詢參數
        Map params = new LinkedHashMap<>();
        params.put("key", APP_KEY);
        params.put("consName", consName);
        params.put("type", type);

        String queryString = params.entrySet().stream()
            .map(e -> e.getKey() + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
            .collect(Collectors.joining("&"));

        String url = API_URL + "?" + queryString;
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(CONNECT_TIMEOUT);
            conn.setReadTimeout(READ_TIMEOUT);
            conn.setRequestProperty("User-Agent", USER_AGENT);
            conn.setInstanceFollowRedirects(false);

            int responseCode = conn.getResponseCode();
            if (responseCode != 200) {
                throw new IOException("HTTP " + responseCode + ": " + conn.getResponseMessage());
            }

            try (InputStream is = conn.getInputStream();
                 BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
                String json = br.lines().collect(Collectors.joining());
                return parseResponse(json);
            }
        } finally {
            if (conn != null) conn.disconnect();
        }
    }

    private ConstellationResult parseResponse(String json) {
        // 簡易 JSON 解析,生產建議用 Jackson/Gson
        // 假設結構:{"error_code":0,"result":{"name":"白羊座",...}}
        int errIdx = json.indexOf("\"error_code\":");
        if (errIdx >= 0) {
            int errVal = Integer.parseInt(json.substring(errIdx + 13).split("[,} ]")[0]);
            if (errVal != 0) {
                int reasonIdx = json.indexOf("\"reason\":\"");
                String reason = reasonIdx >= 0 ? 
                    json.substring(reasonIdx + 10).split("\"")[0] : "Unknown error";
                throw new IllegalStateException("API Error " + errVal + ": " + reason);
            }
        }
        // 提取 result 物件字段(此處略,實際用 JSON 庫)
        // return new ConstellationResult(...);
        return null; // 佔位
    }
}

現代化寫法:Java 11+ HttpClient(推薦)

public class ModernJuheClient {
    private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(5))
        .build();
    private static final String API_URL = "https://web.juhe.cn:8080/constellation/getAll";
    private static final String APP_KEY = "YOUR_APP_KEY";

    public CompletableFuture getFortuneAsync(String consName, String type) {
        String query = "key=" + APP_KEY + "&consName=" + URLEncoder.encode(consName, UTF_8) 
                     + "&type=" + type;
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(API_URL + "?" + query))
            .timeout(Duration.ofSeconds(10))
            .header("User-Agent", "Java 11 HttpClient")
            .GET()
            .build();

        return HTTP_CLIENT.sendAsync(request, BodyHandlers.ofString(StandardCharsets.UTF_8))
            .thenApply(HttpResponse::body)
            .thenApply(this::parseJson); // 用 Jackson ObjectMapper 解析
    }
}

Spring Boot 整合:RestTemplate / WebClient

@Configuration
public class JuheConfig {
    @Value("${juhe.app-key}")
    private String appKey;

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplateBuilder()
            .setConnectTimeout(Duration.ofSeconds(5))
            .setReadTimeout(Duration.ofSeconds(10))
            .build();
    }

    @Bean
    public WebClient webClient() {
        return WebClient.builder()
            .baseUrl("https://web.juhe.cn:8080")
            .defaultHeader(HttpHeaders.USER_AGENT, "Spring Boot App")
            .build();
    }
}

@Service
public class FortuneService {
    private final WebClient webClient;
    private final String appKey;

    public FortuneService(WebClient webClient, @Value("${juhe.app-key}") String appKey) {
        this.webClient = webClient; this.appKey = appKey;
    }

    public Mono getFortune(String consName, String type) {
        return webClient.get()
            .uri(uriBuilder -> uriBuilder.path("/constellation/getAll")
                .queryParam("key", appKey)
                .queryParam("consName", consName)
                .queryParam("type", type)
                .build())
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference>() {})
            .map(ApiResponse::getResult);
    }
}

錯誤處理與重試策略

  • 超時設置:連接 3-5s,讀取 10-15s,防止卡死線程。
  • 重試機制:Resilience4j 或 Spring Retry 配置指數退避重試(針對 5xx、網絡異常)。
  • 熔斷器:連續失敗達閾值快速失效,避免雪崩。
  • 緩存:運勢數據日級緩存(Redis/Caffeine),減少外部調用。
  • 密鑰管理:AppKey 放配置中心/環境變量,絕不硬編碼。

測試驗證

@Test
void testGetFortune() throws Exception {
    JuheConstellationClient client = new JuheConstellationClient();
    ConstellationResult result = client.getFortune("白羊座", "today");
    assertNotNull(result);
    assertEquals("白羊座", result.name());
    System.out.println("今日綜合: " + result.overall());
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved