关于淘宝接口每次最多取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);
}
}
相关推荐
5. **安全性考虑**:在实现批量删除时,需要防止恶意用户通过修改请求参数导致大量数据被误删。可以通过校验用户权限、确认待删除数据的合法性等方式来增加安全性。 综上所述,SSH整合在分页和批量删除方面提供了...
- JavaBean:封装数据对象,便于数据传输和操作。 - 数据库连接池:管理数据库连接,提高效率。 - SQL语句:用于与数据库交互,执行CRUD操作。 通过阅读提供的博文链接(已省略,因为无法直接访问),开发者可以...
在这个项目中,“webform_三层_增删改_分页_批量删除”涉及到的是基于WebForm的三层架构(数据访问层、业务逻辑层、表示层)实现的数据管理功能,包括基本的CRUD(创建Create、读取Read、更新Update、删除Delete)...
4. **分页功能**:为了优化用户体验,封装的表格可能会内置分页功能,自动处理分页请求和数据更新,同时提供分页参数的配置,如每页条数、当前页数等。 5. **排序和筛选**:表格可能支持列的排序和筛选,开发者可以...
"原创-自定义分页"是一个自定义的分页控件,由开发者根据实际需求进行设计和实现,区别于常见的预封装分页组件。在本次修订中,开发者主要解决了之前版本中存在的问题,并增加了新的功能,如批量数据的分批展示。 ...
10. **批量请求**:封装可以支持并发请求(axios.all)或序列化请求,方便处理多个相关但不依赖的请求。 通过以上的封装,开发者可以更专注于业务逻辑,而不是网络请求的细节,从而提高开发效率和代码质量。在提供...
JavaBean是一种符合特定规范的Java类,常用于封装数据和业务逻辑。在这个项目中,JavaBean可能被用来表示用户对象,包含用户名、密码等属性,以及相应的getter和setter方法。它还可能包含验证用户登录的逻辑,这样...
Java 分页插件Valuelist是一款用于Java Web开发中的实用工具,主要目的是为了在处理大量数据时提高性能和用户体验,通过高效地分页显示数据,避免一次性加载所有数据导致内存压力过大。Valuelist源码的分析对于理解...
Datagrid通过Ajax请求获取服务器端数据,Action返回的应为JSON格式的分页数据,包括总记录数、当前页数据等。 9. **动态加载与分页显示**: Datagrid根据返回的JSON数据自动进行分页渲染,用户可以通过改变每页条...
在Web应用中,当数据量过大时,分页是必不可少的,它能帮助用户更高效地浏览和管理信息。在JSP中,分页通常通过SQL查询和编程逻辑实现。例如,我们可以使用LIMIT和OFFSET关键字在数据库查询中限制返回的记录数,然后...
为了简化使用,我们可以封装一组接口JS,将数据请求、分页、排序等操作抽象出来,方便在多个页面中重用。例如,我们可以创建一个名为`FlexigridService.js`的文件,包含以下方法: - `initGrid(gridId, url, ...
8. **Image Downloader工具**:在压缩包中的"Image Downloader"可能是一个已经封装好的图片批量下载工具,它可以简化上述步骤,只需输入关键词和目标保存路径,就能自动完成下载。使用此类工具时,注意查看其功能和...
了解了这些基本知识后,开发者可以基于这些点进一步优化功能,比如添加确认对话框、分页加载用户、异步加载数据等,提高用户体验。同时,为了保证安全性,应避免SQL注入攻击,对用户提交的数据进行有效验证和过滤。...
当你点击增删改按钮时,前端会封装JSON数据并发送到后端,后端解析JSON,执行相应的数据库操作,然后返回结果或者确认信息,前端再根据返回的结果更新视图。 学习这个例子,你可以了解到如何在EasyUI中配置表格的列...
批量操作允许一次发送多个请求,提高效率,如`bulkExecute(List< BulkRequest > requests)`。聚合查询能进行复杂的数据统计,例如`executeAggregation(String index, String type, AggregationBuilder ...
APIJSON支持动态SQL,允许在请求中指定查询条件、排序方式、分页参数等,后端根据这些参数自动生成并执行相应的SQL语句,提高了灵活性。 3. **安全机制**: APIJSON提供了一套内置的安全机制,如防止SQL注入、XSS...
可能包括了服务器端的API接口定义、数据库连接类、Android客户端的网络请求封装类以及相应的数据模型类。通过分析和学习这个项目,开发者可以更好地理解如何在Android应用中实现与远程数据库的交互,同时避免直接...
2. **JavaBean**: JavaBean是一种遵循特定规范的Java类,通常用于封装数据和业务逻辑。在本系统中,JavaBean可能被用来代表好友的信息,如用户名、密码、联系方式等,提供getter和setter方法以便于JSP和Servlet之间...
10. **性能优化**:在处理大量数据或频繁请求时,需要考虑性能优化,如使用缓存、批量处理请求、减少HTTP请求次数等。 综上所述,AJAX开发简略pdf文档可能会涵盖这些基本概念和应用,帮助开发者掌握如何有效地使用...
在JSP页面上,我们可以使用`<form>`标签定义表单,`<input>`标签收集数据,而`<jsp:useBean>`和`<jsp:setProperty>`标签用于创建和设置JavaBean的属性,这个JavaBean通常用来封装用户提交的数据。之后,这些数据可以...