`

分页批量请求数据封装

阅读更多

关于淘宝接口每次最多取100个,需要分页获取的封装

总体思路采取迭代器的方式来多次发送请求.

 

TOPCollection<TOPArticleOrder> orders = session.getArticleOrdersByNick(articleCode, start, end,nick);

size = saveOrders(orders.toList());

 

最终调用TOPCollection中的toList()方法,采用迭代器的方式分页获取数据

迭代器的实现为 TOPCollectionIterator 调用hasnext方法,实际调用writer.hasNext()

write的实现类 CollectionWriter 最终通过 session.execute 来执行分页发送请求的处理.

 

----------------------

 

 

import java.math.BigDecimal;

import java.util.Date;

import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.bstek.common.bean.PropertiesMapping;

import com.bstek.common.lang.AssertUtils;

import com.bstek.common.lang.convert.ConverterUtils;

import com.hupun.crmbatch.service.top.TOPSession;

import com.hupun.crmbatch.service.top.bean.article.TOPArticleOrder;

import com.hupun.crmbatch.service.top.client.AbstractTOPSession;

import com.hupun.crmbatch.service.top.exception.TOPException;

import com.hupun.crmbatch.service.top.exception.TOPExceptionConstants;

import com.taobao.api.TaobaoRequest;

import com.taobao.api.domain.ArticleBizOrder;

import com.taobao.api.request.VasOrderSearchRequest;

import com.taobao.api.response.VasOrderSearchResponse;

 

/**

 * TOP 应用订购订单获取器

 */

public class TOPArticleOrdersGetter extends TOPCollectionHandler<ArticleBizOrder, TOPArticleOrder, VasOrderSearchResponse> {

 

private String code;

 

private Date start;

private Date end;

 

protected int pageNo;

protected int pageSize;

/**

* 订购用户昵称

*/

private String nick;

 

 

/**

* 构造函数

* @param session TOP 会话

*/

public TOPArticleOrdersGetter(AbstractTOPSession session) {

super(session);

 

pageNo = 1;

pageSize = 200;

}

 

public String getCode() {

return code;

}

 

public Date getEnd() {

return end;

}

 

public String getRequesInfo() {

return TOPHandleMessages.top_article_orders_getter.format(code, start, end, pageNo);

}

 

public TaobaoRequest<VasOrderSearchResponse> getRequest() throws TOPException {

VasOrderSearchRequest req = new VasOrderSearchRequest();

if (AssertUtils.UNFORCE.empty(code))

throw new TOPException(TOPExceptionConstants.Exp_param_missing, TOPHandleMessages.param_article_code);

req.setArticleCode(code);

 

if (start != null && end != null && start.before(end)) {

req.setStartCreated(start);

req.setEndCreated(end);

}

 

if (!StringUtils.isEmpty(nick)){

req.setNick(nick);

}

 

req.setPageNo(Long.valueOf(pageNo));

req.setPageSize(Long.valueOf(pageSize));

return req;

}

 

public Date getStart() {

return start;

}

 

public boolean isPrivate() {

return true;

}

 

public TOPException parseError(String code, String msg, TOPSession session) {

return null;

}

 

public void setCode(String code) {

this.code = code;

}

 

public void setEnd(Date end) {

this.end = end;

}

 

public void setStart(Date start) {

this.start = start;

}

 

protected Long collectTotal(VasOrderSearchResponse response) {

return response.getTotalItem();

}

 

protected TOPArticleOrder createData() {

return new TOPArticleOrder();

}

 

protected PropertiesMapping createMapping() {

PropertiesMapping mapping = new PropertiesMapping(10);

mapping.append("articleCode", "articleCode");

mapping.append("orderId", "orderID");

mapping.append("articleName", "name");

mapping.append("create", "created");

mapping.append("fee", "fee");

mapping.append("itemCode", "itemCode");

mapping.append("orderCycleStart", "cycleStart");

mapping.append("orderCycleEnd", "cycleEnd");

mapping.append("nick", "nick");

mapping.append("totalPayFee", "payment");

return mapping;

}

 

protected TOPArticleOrder doTransform(ArticleBizOrder data) {

return getTransformer().transform(data);

}

 

protected List<ArticleBizOrder> getList(VasOrderSearchResponse response) {

return response.getArticleBizOrders();

}

 

protected boolean hasNext() {

return (getTotal() + (pageSize - 1)) / pageSize > pageNo;

}

 

protected void moveNext() {

pageNo++;

}

 

protected Object transform(String source, String target, Object value) throws RuntimeException {

if ("fee".equalsIgnoreCase(source)) {

return ConverterUtils.NORMAL.convert(value, BigDecimal.class).divide(BigDecimal.valueOf(100));

} else if ("totalPayFee".equalsIgnoreCase(source)) {

return ConverterUtils.NORMAL.convert(value, BigDecimal.class).divide(BigDecimal.valueOf(100));

}

return super.transform(source, target, value);

}

 

public String getNick() {

return nick;

}

 

public void setNick(String nick) {

this.nick = nick;

}

 

}

 

 

-----------------------------------------

 

import java.util.Collection;

import java.util.Iterator;

 

import com.bstek.common.bean.PropertiesMapping;

import com.bstek.common.lang.proxy.ProxyUtils;

import com.hupun.crmbatch.service.top.bean.TOPCollection;

import com.hupun.crmbatch.service.top.bean.TOPCollection.TOPCollectionWriter;

import com.hupun.crmbatch.service.top.client.AbstractTOPSession;

import com.taobao.api.TaobaoResponse;

 

/**

 * TOP 平台集合数据调用处理器

 */

public abstract class TOPCollectionHandler<S, R, T extends TaobaoResponse> implements TOPHandler<TOPCollection<R>, T> {

 

/**

* 集合元素转换器

*/

protected class CollectionElementTransformer extends TOPDataTransformer<S, R> {

 

public Object transform(String source, String target, Object value) throws RuntimeException {

return TOPCollectionHandler.this.transform(source, target, value);

}

 

protected R createData() {

return TOPCollectionHandler.this.createData();

}

 

protected PropertiesMapping createMapping() {

return TOPCollectionHandler.this.createMapping();

}

}

 

/**

* 集合写入器

*/

protected class CollectionWriter extends TOPCollectionWriter<R> {

 

public void setTotal(int size) {

super.setTotal(size);

TOPCollectionHandler.this.setTotal(size);

}

 

protected boolean hasNext() {

return TOPCollectionHandler.this.hasNext();

}

 

protected void nextBatch() {

moveNext();

for (int i = 0;;) {

try {

session.execute(TOPCollectionHandler.this, isLog());

break;

} catch (Exception e) {

if (i++ >= 5) throw ProxyUtils.wrapThrowable(e, RuntimeException.class);

}

try {

Thread.sleep(500);

} catch (InterruptedException e) {

// ignore

}

}

}

}

 

protected final AbstractTOPSession session;

private int total;

private CollectionWriter writer;

 

private TOPDataTransformer<S, R> transformer;

 

/**

* 构造函数

* @param session TOP 会话

*/

protected TOPCollectionHandler(AbstractTOPSession session) {

this.session = session;

}

 

public TOPCollection<R> getResult(T response) {

if (writer == null) writer = new CollectionWriter();

Long total = collectTotal(response);

if (total != null) writer.setTotal(total.intValue());

Collection<? extends S> list = getList(response);

if (list != null) doTransform(list, writer);

return writer.getCollection();

}

 

/**

* 提取总数量 请求不返回总数量,返回 <code>null</code>

* @param response 请求返回结果

* @return 总数量

*/

protected abstract Long collectTotal(T response);

 

/**

* 创建元素对象

* @return 元素对象实例

*/

protected R createData() {

return null;

}

 

/**

* 创建属性映射关系

* @return 属性映射关系

*/

protected PropertiesMapping createMapping() {

return null;

}

 

/**

* 执行列表数据转换

* @param list 源数据集

* @param writer 集合写入器

*/

protected void doTransform(Collection<? extends S> list, CollectionWriter writer) {

for (Iterator<? extends S> it = list.iterator(); it.hasNext(); it.remove()) {

writer.add(doTransform(it.next()));

}

}

 

/**

* 执行数据转换

* @param data 源数据

* @return 结果数据

*/

protected abstract R doTransform(S data);

 

/**

* 获取结果数据列表

* @param response 请求返回结果

* @return 数据列表

*/

protected abstract Collection<? extends S> getList(T response);

 

/**

* 获取总数量

* @return 总数量

*/

protected int getTotal() {

return total;

}

 

/**

* 获取数据转换器

* @return 转换器

*/

protected TOPDataTransformer<S, R> getTransformer() {

if (transformer == null) transformer = new CollectionElementTransformer();

return transformer;

}

 

/**

* 是否存在下一批

* @return 是、否

*/

protected abstract boolean hasNext();

 

/**

* 是否记录日志

* @return 是、否

*/

protected boolean isLog() {

return true;

}

 

/**

* 移动条件至下一批

*/

protected abstract void moveNext();

 

/**

* 设置总数量

* @param size 总数量

*/

protected void setTotal(int size) {

this.total = size;

}

 

/**

* 转换属性值

* @param source 源属性名

* @param target 目标属性名

* @param value 属性值

* @return 目标值

* @throws RuntimeException

*/

protected Object transform(String source, String target, Object value) throws RuntimeException {

return value;

}

}

 

 

---------------------------------

 

 

package com.hupun.crmbatch.service.top.handlers;

 

import com.hupun.crmbatch.service.top.exception.TOPException;

import com.taobao.api.TaobaoRequest;

import com.taobao.api.TaobaoResponse;

 

/**

 * TOP 平台调用处理器

 */

public interface TOPHandler<R, S extends TaobaoResponse> {

 

/**

* 获取请求描述信息

* @return 描述信息

*/

public String getRequesInfo();

 

/**

* 获取请求信息

* @return TOP 请求

* @throws TOPException

*/

public TaobaoRequest<S> getRequest() throws TOPException;

 

/**

* 获取处理结果

* @param response TOP 返回结果

* @return 处理结果

*/

public R getResult(S response);

}

 

---------------------------------------

 

 

 

import java.io.Serializable;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

import java.util.List;

import java.util.NoSuchElementException;

 

/**

 * TOP 数据集合体

 */

public class TOPCollection<E> implements Serializable, Iterable<E> {

 

/**

* TOP 数据集合体写入器

*/

public static abstract class TOPCollectionWriter<E> {

 

private TOPCollection<E> collection;

 

/**

* 构造函数

*/

protected TOPCollectionWriter() {

}

 

/**

* 添加 TOP 数据

* @param item TOP 数据

*/

public void add(E item) {

if (collection == null) collection = new TOPCollection(this, 10, false);

collection.add(item);

}

 

/**

* 获取数据集合体

* @return 集合体

*/

public TOPCollection<E> getCollection() {

if (collection == null) collection = new TOPCollection(this, 10, false);

return collection;

}

 

/**

* 设置总数量

* @param size 总数量

*/

public void setTotal(int size) {

if (collection == null) collection = new TOPCollection(this, size, true);

}

 

/**

* 是否有下一批

* @return 是、否

*/

protected abstract boolean hasNext();

 

/**

* 获取下一批数据

*/

protected abstract void nextBatch();

}

 

/**

* TOP 数据集合体迭代器

*/

protected class TOPCollectionIterator implements Iterator<E> {

 

private Entry current;

private long last;

 

protected TOPCollectionIterator() {

current = head;

last = System.currentTimeMillis();

}

 

@Override

public boolean hasNext() {

if (current.next == head) {

synchronized (head) {

if (current.next == head && writer.hasNext()) {

long l = System.currentTimeMillis();

if (l == last) {

try {

Thread.sleep(1);

} catch (InterruptedException e) {

}

}

writer.nextBatch();

last = System.currentTimeMillis();

return current.next != head;

} else {

return false;

}

}

} else if (current.next == null) {

return false;

}

return true;

}

 

@Override

public E next() {

current = current.next;

return current == null ? null : current.value;

}

 

@Override

public void remove() {

if (current == head) return;

Entry tmp = current.previous;

current.remove();

current = tmp;

}

}

 

class Entry implements Serializable {

private static final long serialVersionUID = 57961385403762668L;

 

private Entry next;

private Entry previous;

private final E value;

 

/**

* 构造函数

* @param value 元素值

*/

protected Entry(E value) {

this.value = value;

}

 

/**

* 移除当前元素

*/

public void remove() {

if (this == head) throw new NoSuchElementException();

synchronized (head) {

if (previous != null) previous.next = next;

if (next != null) next.previous = previous;

previous = null;

next = null;

size--;

}

}

 

/**

* 设置上一个元素项

* @param ele 元素项

* @param append 是否增加

*/

public void setPrevious(Entry ele, boolean append) {

if (ele == null) return;

synchronized (head) {

if (previous != null) previous.next = ele;

ele.previous = previous;

ele.next = this;

previous = ele;

if (append) size++;

}

}

}

 

private static final long serialVersionUID = -6163119051025582037L;

 

private transient int size;

private transient Entry head;

 

private final TOPCollectionWriter writer;

private final boolean isTotal;

protected int total;

 

/**

* 构造函数

*/

protected TOPCollection() {

this(null, 0, true);

}

 

/**

* 构造函数

* @param writer 集合体写入器

* @param initSize 初始数量

* @param isTotal 是否总计

*/

protected TOPCollection(TOPCollectionWriter<E> writer, int initSize, boolean isTotal) {

size = 0;

head = new Entry(null);

head.setPrevious(head, false);

 

this.isTotal = isTotal;

total = initSize;

this.writer = writer;

}

 

/**

* 首个元素

* @return 元素值 集合为空返回 <code>null</code>

*/

public E first() {

Iterator<E> it = iterator();

return it.hasNext() ? null : it.next();

}

 

/**

* 导入到目标列表中

* @param list 目标列表

*/

public void importTo(Collection<E> list) {

for (Iterator<E> it = iterator(); it.hasNext();) {

list.add(it.next());

}

}

 

/**

* 是否为空

* @return 是、否

*/

public boolean isEmpty() {

return !iterator().hasNext();

}

 

@Override

public Iterator<E> iterator() {

return new TOPCollectionIterator();

}

 

/**

* 获取数量

* @return 数量

*/

public int size() {

if (isTotal) {

return total;

} else {

throw new UnsupportedOperationException();

}

}

 

/**

* 转换为列表

* @return 列表

*/

public List<E> toList() {

List<E> list = new ArrayList(size);

importTo(list);

return list;

}

 

/**

* 添加元素

* @param o 元素

*/

protected void add(E o) {

Entry ele = new Entry(o);

head.setPrevious(ele, true);

}

 

/**

* 序列化读取

* @param s 序列化输入流

* @throws java.io.IOException

* @throws ClassNotFoundException

*/

private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {

s.defaultReadObject();

 

int size = s.readInt();

 

head = new Entry(null);

head.setPrevious(head, false);

 

for (int i = 0; i < size; i++)

head.setPrevious(new Entry((E) s.readObject()), true);

}

 

/**

* 序列化写入

* @param s 序列化输出流

* @throws java.io.IOException

*/

private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {

s.defaultWriteObject();

 

s.writeInt(size);

 

for (Entry e = head.next; e != head; e = e.next)

s.writeObject(e.value);

}

}

 

分享到:
评论

相关推荐

    ssh整合的分页、批量删除

    5. **安全性考虑**:在实现批量删除时,需要防止恶意用户通过修改请求参数导致大量数据被误删。可以通过校验用户权限、确认待删除数据的合法性等方式来增加安全性。 综上所述,SSH整合在分页和批量删除方面提供了...

    通用的JSP分页+增删改查+批量删除

    - JavaBean:封装数据对象,便于数据传输和操作。 - 数据库连接池:管理数据库连接,提高效率。 - SQL语句:用于与数据库交互,执行CRUD操作。 通过阅读提供的博文链接(已省略,因为无法直接访问),开发者可以...

    webform_三层_增删改_分页_批量删除

    在这个项目中,“webform_三层_增删改_分页_批量删除”涉及到的是基于WebForm的三层架构(数据访问层、业务逻辑层、表示层)实现的数据管理功能,包括基本的CRUD(创建Create、读取Read、更新Update、删除Delete)...

    element-ui表格二次封装.zip

    4. **分页功能**:为了优化用户体验,封装的表格可能会内置分页功能,自动处理分页请求和数据更新,同时提供分页参数的配置,如每页条数、当前页数等。 5. **排序和筛选**:表格可能支持列的排序和筛选,开发者可以...

    修订【原创-自定义分页】

    "原创-自定义分页"是一个自定义的分页控件,由开发者根据实际需求进行设计和实现,区别于常见的预封装分页组件。在本次修订中,开发者主要解决了之前版本中存在的问题,并增加了新的功能,如批量数据的分批展示。 ...

    axios的封装,,,,,,,,

    10. **批量请求**:封装可以支持并发请求(axios.all)或序列化请求,方便处理多个相关但不依赖的请求。 通过以上的封装,开发者可以更专注于业务逻辑,而不是网络请求的细节,从而提高开发效率和代码质量。在提供...

    jsp,servlet,javabean个人登陆,分页显示操作

    JavaBean是一种符合特定规范的Java类,常用于封装数据和业务逻辑。在这个项目中,JavaBean可能被用来表示用户对象,包含用户名、密码等属性,以及相应的getter和setter方法。它还可能包含验证用户登录的逻辑,这样...

    java分页插件valuelist

    Java 分页插件Valuelist是一款用于Java Web开发中的实用工具,主要目的是为了在处理大量数据时提高性能和用户体验,通过高效地分页显示数据,避免一次性加载所有数据导致内存压力过大。Valuelist源码的分析对于理解...

    SSh结合Easyui实现Datagrid的分页显示(多个实例)

    Datagrid通过Ajax请求获取服务器端数据,Action返回的应为JSON格式的分页数据,包括总记录数、当前页数据等。 9. **动态加载与分页显示**: Datagrid根据返回的JSON数据自动进行分页渲染,用户可以通过改变每页条...

    jsp实现分页,实现状态管理,实现文件上传

    在Web应用中,当数据量过大时,分页是必不可少的,它能帮助用户更高效地浏览和管理信息。在JSP中,分页通常通过SQL查询和编程逻辑实现。例如,我们可以使用LIMIT和OFFSET关键字在数据库查询中限制返回的记录数,然后...

    列表控件flexigrid的封装

    为了简化使用,我们可以封装一组接口JS,将数据请求、分页、排序等操作抽象出来,方便在多个页面中重用。例如,我们可以创建一个名为`FlexigridService.js`的文件,包含以下方法: - `initGrid(gridId, url, ...

    图片批量下载

    8. **Image Downloader工具**:在压缩包中的"Image Downloader"可能是一个已经封装好的图片批量下载工具,它可以简化上述步骤,只需输入关键词和目标保存路径,就能自动完成下载。使用此类工具时,注意查看其功能和...

    jsp批量删除用户信息

    了解了这些基本知识后,开发者可以基于这些点进一步优化功能,比如添加确认对话框、分页加载用户、异步加载数据等,提高用户体验。同时,为了保证安全性,应避免SQL注入攻击,对用户提交的数据进行有效验证和过滤。...

    easyui增删改很好的例子

    当你点击增删改按钮时,前端会封装JSON数据并发送到后端,后端解析JSON,执行相应的数据库操作,然后返回结果或者确认信息,前端再根据返回的结果更新视图。 学习这个例子,你可以了解到如何在EasyUI中配置表格的列...

    Elasticsearch使用工具类

    批量操作允许一次发送多个请求,提高效率,如`bulkExecute(List&lt; BulkRequest &gt; requests)`。聚合查询能进行复杂的数据统计,例如`executeAggregation(String index, String type, AggregationBuilder ...

    Android代码-后端接口和文档自动化,前端(客户端) 定制返回JSON的数据和结构!

    APIJSON支持动态SQL,允许在请求中指定查询条件、排序方式、分页参数等,后端根据这些参数自动生成并执行相应的SQL语句,提高了灵活性。 3. **安全机制**: APIJSON提供了一套内置的安全机制,如防止SQL注入、XSS...

    Android实现远程数据库的服务端

    可能包括了服务器端的API接口定义、数据库连接类、Android客户端的网络请求封装类以及相应的数据模型类。通过分析和学习这个项目,开发者可以更好地理解如何在Android应用中实现与远程数据库的交互,同时避免直接...

    jsp+mysql+mvc模式管理系统

    2. **JavaBean**: JavaBean是一种遵循特定规范的Java类,通常用于封装数据和业务逻辑。在本系统中,JavaBean可能被用来代表好友的信息,如用户名、密码、联系方式等,提供getter和setter方法以便于JSP和Servlet之间...

    AJAX开发简略pdf文档

    10. **性能优化**:在处理大量数据或频繁请求时,需要考虑性能优化,如使用缓存、批量处理请求、减少HTTP请求次数等。 综上所述,AJAX开发简略pdf文档可能会涵盖这些基本概念和应用,帮助开发者掌握如何有效地使用...

    jsp实现的增删该查

    在JSP页面上,我们可以使用`&lt;form&gt;`标签定义表单,`&lt;input&gt;`标签收集数据,而`&lt;jsp:useBean&gt;`和`&lt;jsp:setProperty&gt;`标签用于创建和设置JavaBean的属性,这个JavaBean通常用来封装用户提交的数据。之后,这些数据可以...

Global site tag (gtag.js) - Google Analytics