Skip to content

ApiOne Spring Boot 集成指南

重要:根据项目分层规范,ApiOne 调用逻辑必须位于 Manager 层,而非 Service 层。

1. application.yml 配置

yaml
apione:
  # 每个 apiName 独立配置 ak/sk/url/region
  apis:
    user-info-query:
      request-url: https://api-one-dev.digitalhainan.com.cn/apione
      ak: ${APIONE_USER_INFO_AK}
      sk: ${APIONE_USER_INFO_SK}
      region: INTRA
      api-name: user.info.query
    user-list-query:
      request-url: https://api-one-dev.digitalhainan.com.cn/apione
      ak: ${APIONE_USER_LIST_AK}
      sk: ${APIONE_USER_LIST_SK}
      region: INTRA
      api-name: user.list.query
    order-info-query:
      request-url: https://api-one-prod.digitalhainan.com.cn/apione
      ak: ${APIONE_ORDER_AK}
      sk: ${APIONE_ORDER_SK}
      region: PUBLIC
      api-name: order.info.query

2. 配置属性类

java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "apione")
public class ApioneProperties {

    // key=业务标识, value=接口配置(含独立 ak/sk/url/region/apiName)
    private Map<String, ApiConfig> apis = new HashMap<>();

    public Map<String, ApiConfig> getApis() {
        return apis;
    }

    public void setApis(Map<String, ApiConfig> apis) {
        this.apis = apis;
    }

    public static class ApiConfig {
        private String requestUrl;
        private String ak;
        private String sk;
        private String region = "INTRA";
        private String apiName;  // 实际接口名称

        // Getters and Setters
        public String getRequestUrl() { return requestUrl; }
        public void setRequestUrl(String requestUrl) { this.requestUrl = requestUrl; }
        public String getAk() { return ak; }
        public void setAk(String ak) { this.ak = ak; }
        public String getSk() { return sk; }
        public void setSk(String sk) { this.sk = sk; }
        public String getRegion() { return region; }
        public void setRegion(String region) { this.region = region; }
        public String getApiName() { return apiName; }
        public void setApiName(String apiName) { this.apiName = apiName; }
    }
}

3. 客户端封装类

java
import cn.com.digitalhainan.apione.sdk.ContentBody;
import cn.com.digitalhainan.apione.sdk.HttpCaller;
import cn.com.digitalhainan.apione.sdk.HttpParameters;
import cn.com.digitalhainan.apione.sdk.HttpReturn;
import okhttp3.MediaType;

import java.util.Map;

/**
 * ApiOne 客户端封装类(每个接口独立配置)
 */
public class ApioneClient {

    private final String requestUrl;
    private final String ak;
    private final String sk;
    private final String region;
    private final String apiName;

    public ApioneClient(String requestUrl, String ak, String sk, String region, String apiName) {
        this.requestUrl = requestUrl;
        this.ak = ak;
        this.sk = sk;
        this.region = region;
        this.apiName = apiName;
    }

    /**
     * 调用 ApiOne 接口
     */
    public String call(String jsonBody) {
        return doCall(jsonBody, null, null, null, "application/json");
    }

    /**
     * 调用 ApiOne 接口(含 Query 参数)
     */
    public String callWithQuery(String jsonBody, Map<String, String> queryParams) {
        return doCall(jsonBody, null, queryParams, null, "application/json");
    }

    /**
     * 调用 ApiOne 接口(含 Path 参数)
     */
    public String callWithPath(String jsonBody, String path) {
        return doCall(jsonBody, path, null, null, "application/json");
    }

    private String doCall(String jsonBody, String path,
                          Map<String, String> queryParams, Map<String, String> headerParams,
                          String mediaType) {
        ContentBody contentBody = new ContentBody(jsonBody != null ? jsonBody : "{}");

        HttpParameters parameters = HttpParameters.builder()
            .api(apiName)
            .region(region)
            .mediaType(MediaType.parse(mediaType))
            .accessKey(ak)
            .secretKey(sk)
            .contentBody(contentBody)
            .requestUrl(requestUrl)
            .build();

        if (path != null && !path.isEmpty()) {
            parameters.setPath(path);
        }
        if (queryParams != null && !queryParams.isEmpty()) {
            parameters.setQueryParamsMap(queryParams);
        }
        if (headerParams != null && !headerParams.isEmpty()) {
            parameters.setHeaderParamsMap(headerParams);
        }

        HttpReturn httpReturn = HttpCaller.getInstance().call(parameters);
        return httpReturn.getResponse();
    }
}

4. 配置类

java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class ApioneConfig {

    @Autowired
    private ApioneProperties apioneProperties;

    // key=业务标识, value=客户端实例
    private final Map<String, ApioneClient> clientMap = new HashMap<>();

    @PostConstruct
    public void init() {
        Map<String, ApioneProperties.ApiConfig> apis = apioneProperties.getApis();
        if (apis != null) {
            apis.forEach((key, config) -> {
                ApioneClient client = new ApioneClient(
                    config.getRequestUrl(),
                    config.getAk(),
                    config.getSk(),
                    config.getRegion(),
                    config.getApiName()
                );
                clientMap.put(key, client);
            });
        }
    }

    public ApioneClient getClient(String apiKey) {
        ApioneClient client = clientMap.get(apiKey);
        if (client == null) {
            throw new IllegalArgumentException("未找到 apiKey '" + apiKey + "' 的 ApiOne 配置");
        }
        return client;
    }

    // 预定义客户端 Bean
    @Bean(name = "userInfoQueryClient")
    public ApioneClient userInfoQueryClient() {
        return getClient("user-info-query");
    }

    @Bean(name = "userListQueryClient")
    public ApioneClient userListQueryClient() {
        return getClient("user-list-query");
    }

    @Bean(name = "orderInfoQueryClient")
    public ApioneClient orderInfoQueryClient() {
        return getClient("order-info-query");
    }
}

5. Manager 层调用示例

分层规范:ApiOne 调用必须位于 Manager 层,Controller -> Manager -> ApiOne。

java
package cn.szhn.demo.business.user.manager.impl;

import cn.szhn.demo.api.user.vo.UserVO;
import cn.szhn.demo.business.user.manager.UserManager;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class UserManagerImpl implements UserManager {

    // 每个 apiName 对应独立的客户端(独立 ak/sk/url/region)
    @Autowired
    @Qualifier("userInfoQueryClient")
    private ApioneClient userInfoQueryClient;

    @Autowired
    @Qualifier("userListQueryClient")
    private ApioneClient userListQueryClient;

    @Autowired
    @Qualifier("orderInfoQueryClient")
    private ApioneClient orderInfoQueryClient;

    @Override
    public UserDTO getUserInfo(String userId) {
        String jsonBody = "{\"userId\":\"" + userId + "\"}";
        String response = userInfoQueryClient.call(jsonBody);
        return JacksonMapper.alwaysMapper.fromJson(response, UserDTO.class);
    }

    @Override
    public List<UserDTO> listUsers(int pageNum, int pageSize) {
        String jsonBody = "{}";
        Map<String, String> queryParams = Map.of(
            "pageNum", String.valueOf(pageNum),
            "pageSize", String.valueOf(pageSize)
        );
        String response = userListQueryClient.callWithQuery(jsonBody, queryParams);
        JavaType listType = JacksonMapper.alwaysMapper.createCollectionType(
            List.class, UserDTO.class);
        List<User> userList2 = JacksonMapper.alwaysMapper.fromJson(response, listType);
        return userList2;
    }

    @Override
    public String getOrderInfo(String orderId) {
        String jsonBody = "{\"orderId\":\"" + orderId + "\"}";
        // 调用订单服务(独立的 ak/sk/url/region)
        return orderInfoQueryClient.call(jsonBody);
    }
}

调用链路

Controller -> Manager (UserManagerImpl) -> ApioneClient -> ApiOne API

每个 apiName 都有独立的配置(ak、sk、url、region),通过 Spring Bean 注入到 Manager 层使用。

Power By 数字海南