野象新媒体接口文档

新媒体对外接口文档


游标分页请求代码示例

<h2>简要描述</h2> <p>获取【用户列表】和【订单列表】接口采用了游标分页的方式获取分页数据,不同于常规分页方式,其接口响应返回的分页信息不同:</p> <h3>游标分页返回数据列表响应结构</h3> <table> <thead> <tr> <th style="text-align: left;">参数名  </th> <th style="text-align: left;">类型    </th> <th>说明                      </th> </tr> </thead> <tbody> <tr> <td style="text-align: left;">cursor  </td> <td style="text-align: left;">String  </td> <td>游标(下次翻页带上该参数)</td> </tr> <tr> <td style="text-align: left;">isLast  </td> <td style="text-align: left;">Boolean  </td> <td>是否最后一页              </td> </tr> <tr> <td style="text-align: left;">list    </td> <td style="text-align: left;">List    </td> <td>数据列表                  </td> </tr> </tbody> </table> <ul> <li> <p><code>cursor</code> 游标相当于分页书签:标识当前页所在位置和下次请求分页数据起始位置;</p> </li> <li><code>isLast</code> 是否最后一页,可用于循环获取数据中的判定条件。</li> </ul> <h3>游标分页返回数据列表响应示例</h3> <p>获取【用户列表】响应:</p> <pre><code class="language-json">{ &amp;quot;code&amp;quot;: 0, &amp;quot;data&amp;quot;: { &amp;quot;cursor&amp;quot;: &amp;quot;69136464311496704_min:614&amp;quot;, &amp;quot;isLast&amp;quot;: false, &amp;quot;list&amp;quot;: [ { &amp;quot;adChannelType&amp;quot;: 5, &amp;quot;adId&amp;quot;: null, &amp;quot;advertiserId&amp;quot;: null, &amp;quot;appId&amp;quot;: 19743565588729856, &amp;quot;code&amp;quot;: 873626316, &amp;quot;createDateTime&amp;quot;: &amp;quot;2024-01-15 00:05:19&amp;quot;, &amp;quot;headImgUrl&amp;quot;: null, &amp;quot;id&amp;quot;: 77552339973046272, &amp;quot;ip&amp;quot;: null, &amp;quot;lastLoginTime&amp;quot;: null, &amp;quot;loginCount&amp;quot;: 0, &amp;quot;memberName&amp;quot;: &amp;quot;游客&amp;quot;, &amp;quot;mobile&amp;quot;: null, &amp;quot;partnerId&amp;quot;: 19743564976361472, &amp;quot;promotionId&amp;quot;: 0, &amp;quot;promotionKeywords&amp;quot;: null, &amp;quot;state&amp;quot;: null, &amp;quot;ua&amp;quot;: null, &amp;quot;updateDateTime&amp;quot;: &amp;quot;2024-01-15 00:05:19&amp;quot; }, { &amp;quot;adChannelType&amp;quot;: 5, &amp;quot;adId&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;advertiserId&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;appId&amp;quot;: 19743565588729856, &amp;quot;code&amp;quot;: 873625742, &amp;quot;createDateTime&amp;quot;: &amp;quot;2023-12-22 18:43:38&amp;quot;, &amp;quot;headImgUrl&amp;quot;: null, &amp;quot;id&amp;quot;: 69136464311496704, &amp;quot;ip&amp;quot;: &amp;quot;101.40.83.18&amp;quot;, &amp;quot;lastLoginTime&amp;quot;: &amp;quot;2023-12-22 18:44:26&amp;quot;, &amp;quot;loginCount&amp;quot;: 3, &amp;quot;memberName&amp;quot;: &amp;quot;游客&amp;quot;, &amp;quot;mobile&amp;quot;: null, &amp;quot;partnerId&amp;quot;: 19743564976361472, &amp;quot;promotionId&amp;quot;: 0, &amp;quot;promotionKeywords&amp;quot;: null, &amp;quot;state&amp;quot;: null, &amp;quot;ua&amp;quot;: &amp;quot;Mozilla/5.0 ... Language/zh_CN ABI/arm64&amp;quot;, &amp;quot;updateDateTime&amp;quot;: &amp;quot;2023-12-22 18:43:38&amp;quot; } ] }, &amp;quot;msg&amp;quot;: &amp;quot;OK&amp;quot;, &amp;quot;traceId&amp;quot;: &amp;quot;761aba3b-394a-49aa-b791-c1b3273027ce&amp;quot; }</code></pre> <h3>示例接口</h3> <ul> <li>【用户列表】接口:2024年4月20日之前版本,后续该接口如有变更,请按最新接口说明修改您的程序。</li> </ul> <h3>编程语言</h3> <ul> <li>JAVA</li> </ul> <h3>外部依赖</h3> <ul> <li>OkHttp:HTTP 客户端框架;</li> <li>Gson:JSON 序列化反序列化库。</li> </ul> <p>引入依赖:</p> <pre><code>&amp;lt;dependencies&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;com.squareup.okhttp3&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;okhttp&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;4.12.0&amp;lt;/version&amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;com.google.code.gson&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;gson&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;2.10.1&amp;lt;/version&amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;/dependencies&amp;gt;</code></pre> <h2>代码</h2> <h3>Main.java</h3> <pre><code class="language-java">package com.col.okhttp.cursor; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import okhttp3.*; import com.google.gson.Gson; import java.lang.reflect.Type; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; public class Main { /** * OkHttpClient 实例 */ private static final OkHttpClient client = new OkHttpClient(); /** * Gson 实例 */ private static final Gson gson = new GsonBuilder() .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create(); /** * 协议 */ private static final String SCHEME = &amp;quot;https&amp;quot;; /** * 主机 */ private static final String HOST = &amp;quot;gateway-partner.nm-serv.cn&amp;quot;; /** * 获取用户列表路径 */ private static final String MEMBER_LIST_PATH = &amp;quot;member/list&amp;quot;; /** * 授权 ID,用于请求头中的 Auth-Id,实际使用时应替换为真实的授权 ID, * 如何获取授权 ID 请参考文档:https://www.showdoc.com.cn/gatewaypartnerv1/10572543503726557 * 注意:实际使用时请勿将【授权 ID】硬编码在代码中,应使用安全的方式存储和管理授权 ID */ private static final String AUTH_ID = &amp;quot;{AUTH_ID}&amp;quot;; /** * 授权 Token,用于请求头中的 Authorization,实际使用时应替换为真实的授权码, * 如何获取授权码 请参考文档:https://www.showdoc.com.cn/gatewaypartnerv1/10572543503726557 * 注意:实际使用时请勿将【授权码】硬编码在代码中,应使用安全的方式存储和管理授权码 */ private static final String AUTHORIZATION = &amp;quot;{AUTHORIZATION}&amp;quot;; /** * 默认分页大小 */ private static final String DEFAULT_SIZE = &amp;quot;100&amp;quot;; /** * 日期时间格式 */ private static final String DATE_TIME_FORMAT = &amp;quot;yyyy-MM-dd HH:mm:ss&amp;quot;; /** * 日期时间格式化器 */ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT); public static void main(String[] args) { // 应用 ID,实际使用时应替换为真实的应用 ID Long appId = 1L; LocalDateTime now = LocalDateTime.now(); LocalDateTime yesterday = now.minusDays(1); String beginDate = yesterday.format(formatter); String endDate = now.format(formatter); List&amp;lt;MemberRes&amp;gt; memberList = getMemberList(appId, null, beginDate, endDate, null, null); if (memberList != null) { handleMemberList(memberList); } } /** * 处理用户列表 * * @param memberList 用户列表 */ private static void handleMemberList(List&amp;lt;MemberRes&amp;gt; memberList) { // 处理数据 // memberList.forEach(System.out::println); } /** * 获取用户列表 * * @param appId 应用 ID * @param memberId 用户 ID * @param beginDate 用户注册开始时间 * @param endDate 用户注册结束时间 * @param lastLoginBeginDate 用户最后登录开始时间 * @param lastLoginEndDate 用户最后登录结束时间 * @return 用户列表 */ private static List&amp;lt;MemberRes&amp;gt; getMemberList(Long appId, Long memberId, String beginDate, String endDate, String lastLoginBeginDate, String lastLoginEndDate) { if (appId == null || appId &amp;lt;= 0) { throw new IllegalArgumentException(&amp;quot;应用 ID 不能为空&amp;quot;); } // region 构造请求参数 Map Map&amp;lt;String, String&amp;gt; params = new HashMap&amp;lt;&amp;gt;(); params.put(&amp;quot;appId&amp;quot;, String.valueOf(appId)); if (memberId != null &amp;amp;&amp;amp; memberId &amp;gt; 0) { params.put(&amp;quot;memberId&amp;quot;, String.valueOf(memberId)); } if (beginDate != null &amp;amp;&amp;amp; !beginDate.isEmpty()) { params.put(&amp;quot;beginDate&amp;quot;, beginDate); } if (endDate != null &amp;amp;&amp;amp; !endDate.isEmpty()) { params.put(&amp;quot;endDate&amp;quot;, endDate); } if (lastLoginBeginDate != null &amp;amp;&amp;amp; !lastLoginBeginDate.isEmpty()) { params.put(&amp;quot;lastLoginBeginDate&amp;quot;, lastLoginBeginDate); } if (lastLoginEndDate != null &amp;amp;&amp;amp; !lastLoginEndDate.isEmpty()) { params.put(&amp;quot;lastLoginEndDate&amp;quot;, lastLoginEndDate); } params.put(&amp;quot;size&amp;quot;, DEFAULT_SIZE); // endregion // 分离路径,用于构造请求 URL,不分离的话,路径中包含的 / 会被转义 String[] paths = MEMBER_LIST_PATH.split(&amp;quot;/&amp;quot;); // 构造请求 URL HttpUrl httpUrl = getHttpUrl(paths, params); // 用户列表 List&amp;lt;MemberRes&amp;gt; memberResList = new ArrayList&amp;lt;&amp;gt;(); try { // 游标分页查询用户列表 ApiResponse&amp;lt;CursorPageRes&amp;lt;MemberRes&amp;gt;&amp;gt; apiResponse; CursorPageRes&amp;lt;MemberRes&amp;gt; cursorPageRes; do { apiResponse = getMemberList(httpUrl); // region 判断响应 if (apiResponse == null) { System.out.println(&amp;quot;apiResponse is null&amp;quot;); return memberResList; } if (apiResponse.getCode() != 0) { System.out.println(&amp;quot;apiResponse.getMsg() = &amp;quot; + apiResponse.getMsg()); System.out.println(&amp;quot;apiResponse.getTraceId() = &amp;quot; + apiResponse.getTraceId()); return memberResList; } if (apiResponse.getData() == null) { System.out.println(&amp;quot;apiResponse.getData() is null&amp;quot;); return memberResList; } // endregion // 获取游标分页响应 cursorPageRes = apiResponse.getData(); if (cursorPageRes.getList() == null || cursorPageRes.getList().isEmpty()) { System.out.println(&amp;quot;cursorPageRes.getList() is null&amp;quot;); return memberResList; } // 添加列表 memberResList.addAll(cursorPageRes.getList()); // 判断是否还有下一页 if (!cursorPageRes.getIsLast()) { // 构造下一页请求 URL // 下一页请求 URL 中包含了游标参数 cursor,用于获取下一页数据 // 其它参数不变,只需修改游标参数 cursor httpUrl = httpUrl.newBuilder().setQueryParameter(&amp;quot;cursor&amp;quot;, cursorPageRes.getCursor()).build(); } } while (!cursorPageRes.getIsLast());// 循环条件:还有下一页 return memberResList; } catch (Exception e) { System.out.println(e.getMessage()); return null; } } /** * 获取用户列表 * * @param url 请求 URL * @return 用户列表 * @throws Exception 异常 */ private static ApiResponse&amp;lt;CursorPageRes&amp;lt;MemberRes&amp;gt;&amp;gt; getMemberList(HttpUrl url) throws Exception { Request request = new Request.Builder() .url(url) .headers(getHeaders()) .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful() &amp;amp;&amp;amp; response.body() != null) { // 获取响应体 String serializedObject = response.body().string(); // 反序列化为 ApiResponse&amp;lt;CursorPageRes&amp;lt;MemberRes&amp;gt;&amp;gt;,可以选用其它序列化反序列化框架 Type type = new TypeToken&amp;lt;ApiResponse&amp;lt;CursorPageRes&amp;lt;MemberRes&amp;gt;&amp;gt;&amp;gt;() { }.getType(); return gson.fromJson(serializedObject, type); } else { throw new RuntimeException(&amp;quot;请求失败&amp;quot;); } } } /** * 构造请求 URL * * @param paths 路径数组 * @param params 请求参数 Map * @return 请求 URL */ private static HttpUrl getHttpUrl(String[] paths, Map&amp;lt;String, String&amp;gt; params) { HttpUrl.Builder builder = new HttpUrl.Builder() .scheme(SCHEME) .host(HOST); for (String path : paths) { builder.addPathSegment(path); // 添加路径 } for (Map.Entry&amp;lt;String, String&amp;gt; entry : params.entrySet()) { builder.addQueryParameter(entry.getKey(), entry.getValue()); // 添加查询参数 } return builder.build(); } /** * 获取请求头 * * @return 请求头 */ private static Headers getHeaders() { return new Headers.Builder() .add(&amp;quot;Auth-Id&amp;quot;, AUTH_ID) // 授权 ID .add(&amp;quot;Authorization&amp;quot;, AUTHORIZATION) // 授权 Token .build(); } } </code></pre> <h3>ApiResponse.java</h3> <pre><code class="language-java">package com.col.okhttp.cursor; import java.io.Serializable; /** * API 响应 * * @param &amp;lt;T&amp;gt; 数据类型 */ public class ApiResponse&amp;lt;T&amp;gt; implements Serializable { /** * 返回码 */ private Integer code; /** * 返回消息 */ private String msg; /** * 链路追踪 ID */ private String traceId; /** * 返回数据 */ private T data; public Integer getCode() { return code; } public String getMsg() { return msg; } public String getTraceId() { return traceId; } public T getData() { return data; } } </code></pre> <h3>CursorPageRes.java</h3> <pre><code>package com.col.okhttp.cursor; import java.io.Serializable; import java.util.List; /** * 游标分页响应 * * @param &amp;lt;T&amp;gt; 数据类型 */ public class CursorPageRes&amp;lt;T&amp;gt; implements Serializable { /** * 游标(下次翻页带上该参数) */ private String cursor; /** * 是否最后一页 */ private Boolean isLast; /** * 数据列表 */ private List&amp;lt;T&amp;gt; list; public String getCursor() { return cursor; } public Boolean getIsLast() { return isLast; } public List&amp;lt;T&amp;gt; getList() { return list; } } </code></pre> <h3>LocalDateTimeTypeAdapter.java</h3> <pre><code class="language-java">package com.col.okhttp.cursor; import com.google.gson.*; import java.lang.reflect.Type; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** * LocalDateTime 类型适配器 */ public class LocalDateTimeTypeAdapter implements JsonSerializer&amp;lt;LocalDateTime&amp;gt;, JsonDeserializer&amp;lt;LocalDateTime&amp;gt; { private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&amp;quot;yyyy-MM-dd HH:mm:ss&amp;quot;); @Override public JsonElement serialize(LocalDateTime localDateTime, Type srcType, JsonSerializationContext context) { return new JsonPrimitive(formatter.format(localDateTime)); } @Override public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return LocalDateTime.parse(json.getAsString(), formatter); } } </code></pre> <h3>MemberRes.java</h3> <pre><code class="language-java">package com.col.okhttp.cursor; import java.io.Serializable; import java.time.LocalDateTime; public class MemberRes implements Serializable { /** * 用户 ID */ private Long id; /** * 用户名称 */ private String memberName; /** * 创建时间 */ private LocalDateTime createDateTime; /** * 更新时间 */ private LocalDateTime updateDateTime; /** * 头像 */ private String headImgUrl; /** * 绑定手机号 */ private String mobile; /** * 所属子分销商 ID */ private Long partnerId; /** * 归属应用 ID */ private Long appId; /** * 推广 ID */ private Long promotionId; /** * 推广链接口令 */ private String promotionKeywords; /** * 登录次数 */ private Integer loginCount; /** * 最近登录时间 */ private LocalDateTime lastLoginTime; /** * 用户 code */ private Long code; /** * 状态:1-正常;2-隐藏 */ private Integer state; /** * IP */ private String ip; /** * 注册 UA */ private String ua; /** * 广告账户 ID */ private String advertiserId; /** * 广告计划 ID */ private String adId; /** * 广告媒体渠道类型 */ private Integer adChannelType; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getMemberName() { return memberName; } public void setMemberName(String memberName) { this.memberName = memberName; } public LocalDateTime getCreateDateTime() { return createDateTime; } public void setCreateDateTime(LocalDateTime createDateTime) { this.createDateTime = createDateTime; } public LocalDateTime getUpdateDateTime() { return updateDateTime; } public void setUpdateDateTime(LocalDateTime updateDateTime) { this.updateDateTime = updateDateTime; } public String getHeadImgUrl() { return headImgUrl; } public void setHeadImgUrl(String headImgUrl) { this.headImgUrl = headImgUrl; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public Long getPartnerId() { return partnerId; } public void setPartnerId(Long partnerId) { this.partnerId = partnerId; } public Long getAppId() { return appId; } public void setAppId(Long appId) { this.appId = appId; } public Long getPromotionId() { return promotionId; } public void setPromotionId(Long promotionId) { this.promotionId = promotionId; } public String getPromotionKeywords() { return promotionKeywords; } public void setPromotionKeywords(String promotionKeywords) { this.promotionKeywords = promotionKeywords; } public Integer getLoginCount() { return loginCount; } public void setLoginCount(Integer loginCount) { this.loginCount = loginCount; } public LocalDateTime getLastLoginTime() { return lastLoginTime; } public void setLastLoginTime(LocalDateTime lastLoginTime) { this.lastLoginTime = lastLoginTime; } public Long getCode() { return code; } public void setCode(Long code) { this.code = code; } public Integer getState() { return state; } public void setState(Integer state) { this.state = state; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getUa() { return ua; } public void setUa(String ua) { this.ua = ua; } public String getAdvertiserId() { return advertiserId; } public void setAdvertiserId(String advertiserId) { this.advertiserId = advertiserId; } public String getAdId() { return adId; } public void setAdId(String adId) { this.adId = adId; } public Integer getAdChannelType() { return adChannelType; } public void setAdChannelType(Integer adChannelType) { this.adChannelType = adChannelType; } } </code></pre>

页面列表

ITEM_HTML