如何用1500行搞定淘宝20000行Java SDK_第1页
如何用1500行搞定淘宝20000行Java SDK_第2页
如何用1500行搞定淘宝20000行Java SDK_第3页
如何用1500行搞定淘宝20000行Java SDK_第4页
如何用1500行搞定淘宝20000行Java SDK_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、挑战淘宝:且看如何用1500行搞定淘宝20000行Java SDK继亚马逊、雅虎、Google等一众知名大公司掀起了开放API的潮流后,淘宝也不甘寂寞,于2009推出了TOP平台,搭上了这趟开放API的顺风车(详细请看为了更好的开发TOP程序,淘宝提供了各种语言的SDK,其中自然少不了编程语言老大Java的SDK。但不幸的是,当我兴致勃勃的将SDK下载下来,准备大干一场的时候,却发现淘宝的Java SDK只是“看上去很美”,用起来却很不爽。让我们分析淘宝给的样例来看看究竟是什么不爽。如下是淘宝给的API调用样例(详见: view plaincopy to clipboardprint?publ

2、ic class ApiDemoTest protected String testUrl = " protected String appkey = "test" protected String secret = "test" protected String nick="alipublic01" protected String sessionID = "alipublic01" protected TaobaoJsonRestClient jsonclient; public ApiDemoTes

3、t() throws TaobaoApiException /*第一步:创建一个TaobaoJsonRestClient对象,此对象负责完成TOP API调用*/ jsonclient = new TaobaoJsonRestClient(testUrl,appkey, secret); public void testItemGet() throws TaobaoApiException /*第二步:生成一个API请求对象,如ItemGetRequest */ ItemGetRequest request = new ItemGetRequest(); /*第三步:设置API调用参数,如se

4、tFields、setNick、setIid*/ request.setFields("iid,num,price,input_pids,product_id,sku.sku_id ,title,outer_id ,props"); request.setNick(nick); request.setIid("e9dd57aaa104aa6cf042e3d71421fea9"); /*第四步:获得一个API响应对象,如ItemGetResponse,此对象由TaobaoJsonRestClient调用API请求对象request生成*/ ItemGetR

5、esponse response = jsonclient .itemGet(request,sessionID,nick); System.out.println(response.getBody(); public class ApiDemoTest protected String testUrl = " protected String appkey = "test" protected String secret = "test" protected String nick="alipublic01" protec

6、ted String sessionID = "alipublic01" protected TaobaoJsonRestClient jsonclient;public ApiDemoTest() throws TaobaoApiException /*第一步:创建一个TaobaoJsonRestClient对象,此对象负责完成TOP API调用*/ jsonclient = new TaobaoJsonRestClient(testUrl,appkey, secret); public void testItemGet() throws TaobaoApiExcepti

7、on /*第二步:生成一个API请求对象,如ItemGetRequest */ItemGetRequest request = new ItemGetRequest(); /*第三步:设置API调用参数,如setFields、setNick、setIid*/ request.setFields("iid,num,price,input_pids,product_id,sku.sku_id ,title,outer_id ,props"); request.setNick(nick); request.setIid("e9dd57aaa104aa6cf042e3d7

8、1421fea9"); /*第四步:获得一个API响应对象,如ItemGetResponse,此对象由TaobaoJsonRestClient调用API请求对象request生成*/ ItemGetResponse response = jsonclient .itemGet(request,sessionID,nick); System.out.println(response.getBody(); 我们基于这个样例来看淘宝Java SDK的调用机制:1) 创建一个TaobaoJsonRestClient对象,此对象负责完成TOP API调用2) 生成一个API请求对象:ItemG

9、etRequest,设置API调用参数3) 获得一个API响应对象:ItemGetResponse,此对象由TaobaoJsonRestClient生成4) 从ItemGetResponse中通过TaobaoItemJSONConvert获取最终的对象; 从样例来看,淘宝的SDK调用机制也没有什么问题:采用面向对象,请求和响应隔离。不过如果你打开SDK的源代码、或者亲自调用几个API体验一下,就会发现淘宝SDK中的实现机制存在如下问题:1)绝大部分代码是非常相似、非常简单的属性定义和操作API相关的类有:请求类、响应类、结果类、转换类,但不同的API这些类都非常类似,都是属性定义、属性get/

10、set操作。我们来看源代码(由于代码太多,省略了绝大部分相似的代码):=Item结果类:view plaincopy to clipboardprint?public class Item extends TaobaoModel private static final long serialVersionUID = 33230486742413888L; private String iid; . (此处省略约70行属性定义). private File image; public String getIid() return iid; public void setIid(String i

11、id) this.iid = iid; (此处省略约300行get/set函数) public File getImage() return image; public void setImage(File image) this.image = image; public class Item extends TaobaoModelprivate static final long serialVersionUID = 33230486742413888L;private String iid;. (此处省略约70行属性定义).private File image;public String

12、 getIid() return iid;public void setIid(String iid) this.iid = iid;(此处省略约300行get/set函数)public File getImage() return image;public void setImage(File image) this.image = image; =Trade类: view plaincopy to clipboardprint?public class Trade extends TaobaoModel private static final long serialVersionUID

13、= -8410518683112517552L; private String sellerNick; (此处省略约150行属性定义). private Boolean is3D; public String getSellerNick() return sellerNick; public void setSellerNick(String sellerNick) this.sellerNick = sellerNick; (此处省略约500行get/set函数) public Boolean getIs3D() return is3D; public void setIs3D(Boolea

14、n is3D) this.is3D = is3D; public class Trade extends TaobaoModel private static final long serialVersionUID = -8410518683112517552L;private String sellerNick; (此处省略约150行属性定义).private Boolean is3D;public String getSellerNick() return sellerNick;public void setSellerNick(String sellerNick) this.seller

15、Nick = sellerNick;(此处省略约500行get/set函数)public Boolean getIs3D() return is3D;public void setIs3D(Boolean is3D) this.is3D = is3D; 2)设计与实现没有分离,每个API都要设计4个不同的类,导致代码量非常庞大我们以SDK的样例来进行分析,分析内容请看代码注释:view plaincopy to clipboardprint?public void testItemGet() throws TaobaoApiException /*调用不同的API,必须new不同的API对象

16、*例如如果要获取交易数据,则要这样写: *TradeGetRequest request = new TradeGetRequest() */; ItemGetRequest request = new ItemGetRequest(); /*调用不同的API,必须调用此API特有的设置函数进行参数设置。 *例如ItemGetRequest有setIid函数,TradeGetRequest有setTid函数,无法通过通用的 *方法来设置API参数 */ request.setFields("iid,num,price,input_pids,product_id,sku.sku_id

17、,title,outer_id ,props"); request.setNick(nick); request.setIid("e9dd57aaa104aa6cf042e3d71421fea9"); /*此处代码有几个问题: *1)调用不同的API,必须调用此API特有的响应函数进行处理 * 例如如果要获取交易数据,必须使用TradeGetResponse对象 *2)每个结果对象,jsonclient都必须有一个对应的get函数,例如Item对象是itemGet * 函数, Trade对象是tradeGet函数 *3)在每个get函数里面,又会有不同的Conve

18、rter对象来负责从JSON或者XML文档 * 转换为对象:TaobaoItemJSONConvert(转换为Item对象) 和 * TaobaoTradeJSONConvert(转换为Trade对象) */ ItemGetResponse response = jsonclient .itemGet(request,sessionID,nick); System.out.println(response.getBody(); public void testItemGet() throws TaobaoApiException /*调用不同的API,必须new不同的API对象*例如如果要获取

19、交易数据,则要这样写:*TradeGetRequest request = new TradeGetRequest()*/;ItemGetRequest request = new ItemGetRequest();/*调用不同的API,必须调用此API特有的设置函数进行参数设置。*例如ItemGetRequest有setIid函数,TradeGetRequest有setTid函数,无法通过通用的*方法来设置API参数*/request.setFields("iid,num,price,input_pids,product_id,sku.sku_id ,title,outer_id

20、,props"); request.setNick(nick); request.setIid("e9dd57aaa104aa6cf042e3d71421fea9"); /*此处代码有几个问题:*1)调用不同的API,必须调用此API特有的响应函数进行处理* 例如如果要获取交易数据,必须使用TradeGetResponse对象*2)每个结果对象,jsonclient都必须有一个对应的get函数,例如Item对象是itemGet * 函数, Trade对象是tradeGet函数*3)在每个get函数里面,又会有不同的Converter对象来负责从JSON或者XML文

21、档* 转换为对象:TaobaoItemJSONConvert(转换为Item对象) 和* TaobaoTradeJSONConvert(转换为Trade对象)*/ItemGetResponse response = jsonclient .itemGet(request,sessionID,nick); System.out.println(response.getBody(); 用代码统计工具统计,代码量是21296行代码;加上大部分代码相似,很难阅读。 3)API的任何变更,SDK都必须更新,开发者也必须相应更新,耦合联动关系很强例如:ItemGetRequest的setIid修改为set

22、IID,那么所有使用了setIid的地方都必须修改,然后重新编译。又如:如果在SDK2.0中某个API增加一个参数,或者增加了新的API,而你又必须使用的话,那么就必须切换到SDK2.0,这个切换可不是改个名字或者增删一行代码那么简单,你需要将原来的jar包删除,然后倒入新的jar包,然后再到SDK2.0中找到对应的API,还要寄希望于淘宝不要把其它API相关对象的定义给改了。 加上淘宝有的代码并没有开放,如果一旦出问题,调试和修改几乎不可能的。基于这些原因,我决定自己动手建立一套比淘宝SDK更简单、更容易理解和使用的调用机制。既然想要比淘宝SDK更优秀,就必须解决淘宝SDK存在的问题,那么来

23、看我是如何设计的:1)"API请求"(如ItemGetRequest)、"API响应"(如ItemGetResponse)、"API结果"(如Item)本质上都是"数据结构",不需要完成什么具体的操作,因此可以通过XML来进行定义,而不需要在代码中进行定义,这一指导思想是整个设计的核心思想;2)不同的API请求只是参数不同,因此封装参数为对象;3)不同的API响应只是属性不同,因此封装属性为对象;由于参数和属性都是"名值对"的操作,因此参数对象和属性对象可以设计为同一个对象:"名值对&

24、quot;对象;4)设计一种通用的get/set操作,避免大量相似的代码。 来看我的设计的主要的类:1) TOPApiClient:总的处理类,负责调用API,处理API返回结果;2) TOPApiResultHandler:负责解析XML文档,生成具体的结果对象TOPApiResult;3) TOPFactory:根据XML文件生成TOPApiRequest原型和TOPApiResult原型;4) TOPApiRequest:API请求对象,由TOPFactory创建原型,调用的时候只能进行参数值的设置,不能进行参数设置;5) TOPApiResult:API返回结果对象,由TOPFacto

25、ry创建原型,TOPApiResultHandler根据原型进行赋值;由于存在嵌套对象,因此采用装饰者模式进行设计;6) TOPNameValuePair:名值对对象,用于TOPApiRequest参数设置和TOPApiResult属性设置;7) TOPBoolPairTOPFilePair:具体的参数对象,根据不同的类型定义不同的对象,例如TOPBoolPair、TOPIntegerPair、TOPFloatPair、TOPStringPair等; TOPFactory设计说明:本来也可以不用从XML文件读取定义,而直接在编码的时候边添加参数边赋值参数,但这样做存在如下问题:1) 依赖编码人

26、员来保证TOPApiRequest和TOPApiResult的正确性,而人与机器相比是最不可靠的,而且不同的人水平不一样,没法做到统一;而由XML文件定义可以通过机器来保证定义正确性,即使错误了,只要查XML文件即可,不需要到代码中一个一个去找;2) 每次使用TOPApiRequest和TOPApiResult都需要人工添加参数,调用100次就要添加100次,重复代码太多;而由XML文件定义后,只在TOPFactory添加参数,其它地方只要设置参数值即可,不会出现大量重复代码。TOPNameValuePair设计说明:本来可以全部用"字符串"的形式来保存名值对,但这样做存在

27、两个问题:1) 所有调用者都必须自己完成特定类型和字符串类型之间的转换,例如int->string或者string->int,因此有100次调用就要转换100次,而直接根据类型分开定义,只需要一次转换即可;2) 字符串形式无法做静态检查,例如:本来是要设置一个int值,结果错误的赋值为2010xyz,这种情况字符串形式没法检测,而按照类型分开定义则可以完成检测。 我们来看新的设计方案后的样例:view plaincopy to clipboardprint?public static void main(String args) /*创建TOPApiClient*/ TOPApiC

28、lient client = new TOPApiClient(); client.setSession(session); /*创建TOPFactory*/ TOPFactory factory = new TOPFactory(); /*由TOPFactory根据API名称创建API请求request*/ TOPApiRequest request = factory.getTOPApiRequest(“taobao.trades.bought.get”); /*根据参数名称设置API参数*/ request.setApiParameter("status", &quo

29、t;TRADE_FINISHED"); /*由TOPFactory根据结果名称创建API结果原型*/ TOPApiResult resultProto = factory.getTOPApiResult(“taobao.trades.bought.get.result”); /*根据结果来生成请求的fields,避免像淘宝SDK那样手工填写*/ request.setApiParameter("fields", resultProto.getChildProto("trade").getApiFields(""); /*运行

30、API*/ int errorCode = client.executeApi(CONST.getCurrentEnv(), request) ; if( errorCode = CONST.TOP_API_ERRCODE_OK) /*调用成功后,解析XML结果文件,获得最终的结果finalResult*/ TOPApiResult finalResult = client.getResultObject(request.getApiResultFileName(), resultProto); finalResult.printAllFields(""); else Sy

31、stem.out.print("Failed to call TOP api, error code is : " + errorCode + "n"); public static void main(String args) /*创建TOPApiClient*/ TOPApiClient client = new TOPApiClient(); client.setSession(session); /*创建TOPFactory*/ TOPFactory factory = new TOPFactory(); /*由TOPFactory根据API名称

32、创建API请求request*/ TOPApiRequest request = factory.getTOPApiRequest(“taobao.trades.bought.get”); /*根据参数名称设置API参数*/ request.setApiParameter("status", "TRADE_FINISHED"); /*由TOPFactory根据结果名称创建API结果原型*/ TOPApiResult resultProto = factory.getTOPApiResult(“taobao.trades.bought.get.result

33、”); /*根据结果来生成请求的fields,避免像淘宝SDK那样手工填写*/ request.setApiParameter("fields", resultProto.getChildProto("trade").getApiFields(""); /*运行API*/ int errorCode = client.executeApi(CONST.getCurrentEnv(), request) ; if( errorCode = CONST.TOP_API_ERRCODE_OK) /*调用成功后,解析XML结果文件,获得最终的结果finalResult*/ TOPApiResult finalResult = client.getResultObject(request.getApiResultFileName(), resultProto); finalResult.printAllFields("");

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论