设为首页 收藏本站
查看: 1075|回复: 0

[经验分享] 实战项目:通过当当API将订单抓取到SAP(一)

[复制链接]

尚未签到

发表于 2015-9-19 09:28:37 | 显示全部楼层 |阅读模式
  公司在当当上经营了一家店铺,通过当当提供的API,用C#写代码,通过NCO3.0调用SAP RFC将订单信息抓取到SAP。
  如果你是新手,在当当网上有店铺,且你公司使用SAP系统,恭喜你,下面这些代码直接复制过去,改下商家编码和密钥就可以直接抓单了。如果你只是当当网有店铺,没有SAP系统,下面这些代码也同样对你有用,你或许要插入自己的数据库,这更简单了。
  需要准备的环境:
  1、  Microsoft Visual Studio 2010 开发环境。
  2、  NCO3.0 (下载地址:http://download.iyunv.com/detail/szlaptop/4635144)
  (VS2010环境下必须这个版本:sapnco30dotnet40P_8-20007347.zip)
  3、  Log4net (百度下,在官方下载)
  4、  在SAP里建2张表,用SAP专业术语,建一个抬头表,建一个行项目表
  5、  当当API手册(在商家后台,公告栏处可以看见)
  
  Step1
  登录当当网商家后台,设置商家接口密码(这些内容当当API里有)
DSC0000.png
  
  注意:
  1、 商家修改接口密码(key)时,需要提供原key值;如果商家是第一次使用该功能,那么可以不输入原key值;
  2、 新key值区分大小写,设置时请特别注意;
  3、 新key值长度为8-20位,不能全部为数字,不能全部为小写字母,不能全部为大写字母;
  4、 如果商家忘记原key值,请联系当当技术支持,进行key值重置。
  Step2
  打开VS2010新建一个Windows窗体应用程序,命名:DangDang
DSC0001.png
  
在解决方案资源管理器,引用里引用NCO3.0的sapnco.dll和sapnco_utils 及 log4net


DSC0002.png
  
右击项目名称DangDang,点击“属性”,打开属性面板:将目标框架里默认的.NET Framework 4 Client Profile 改为:.NET Framework 4。(很重要)

DSC0003.png


在解决方案资源管理器里打开配置文件APP.CONFIG,配置如下:

DSC0004.png

Step3

经过Step2的设置,VS环境这边算是搭建OK了。第3步,我们去SAP建表去(建表详细略)

因为我们这里这是抓取当当订单的信息。所以建2张表,表的字段和含义请熟读当当API手册。


DSC0005.jpg
上面这张图不是完全的,因为截图截不了那么多,下面还有很多字段,这些字段都是根据API手册来设置的,当然你可以灵活的从这些字段中取认为你需要的信息。


DSC0006.jpg
  
这两张表,我都选了”订单编号”做为主键,方便以后关联查询。

Step4

写RFC(写RFC可以参照我之前写的博客)


DSC0007.jpg
  
Source code里的代码很简单。





1  IF IT_ZDDITEM[] IS NOT INITIAL.
2     MODIFY ZDDITEM FROM TABLE IT_ZDDITEM[].
3     IF SY-SUBRC = 0.
4       R_SUBRC = '数据已成功写入ZDDITEM表里'.
5     ENDIF.
6   ENDIF.
7
8     IF IT_ZDDITEMMAS[] IS NOT INITIAL.
9     MODIFY ZDDITEMMAS FROM TABLE IT_ZDDITEMMAS[].
10     IF SY-SUBRC = 0.
11       R_SUBRC = '数据已成功写入ZDDITEMMAS表里'.
12     ENDIF.
13   ENDIF.
  Step5
到第5部了,开始在VS里写代码了。首先要解决的是”验证码算法”,API手册了给了解释:

validateString参数是每个API请求中必须发送的参数,由请求中的其它参数以及后台设置的key值两部分,采用MD5加密生成,具体算法如下:

第一步,把请求中的参数(XML文件以及validateString本身除外),按照参数名称进行正向排序

第二步,把各个参数的值按照GBK编码后,按照排序顺序串联起来(不能有空格)

第三步,把后台设置的key值按照GBK编码后,串接到“第二步”得到的字符串尾部(不能有空格)

第四步,采用MD5算法对“第三步”得到的字符串进行加密,生成validateString的值

好了,我直接上C#代码,将这4步翻译成代码:





1 public static string MD5(string str, string encode)
2         {
3             MD5 md5 = new MD5CryptoServiceProvider();
4             byte[] data = md5.ComputeHash(Encoding.GetEncoding(encode).GetBytes(str));
5             StringBuilder sBuilder = new StringBuilder();
6             for (int i = 0; i < data.Length; i++)
7             {
8                 sBuilder.Append(data.ToString("x2"));
9             }
10             return sBuilder.ToString();
11         }
12         public static string SignTopRequest(IDictionary<string, string> parameters, string key)
13         {
14             IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
15             string str = string.Empty;
16             foreach (var item in sortedParams)
17             {
18                 if (!string.IsNullOrEmpty(item.Value))
19                 {
20                     str += System.Text.Encoding.GetEncoding("GBK").GetString(System.Text.Encoding.Default.GetBytes(item.Value));
21                 }
22             }
23             str += System.Text.Encoding.GetEncoding("GBK").GetString(System.Text.Encoding.Default.GetBytes(key));
24             return MD5(str, "UTF-8");
25         }
26         private static IDictionary<string, string> SplitUrlQuery(string query)
27         {
28             IDictionary<string, string> result = new Dictionary<string, string>();
29
30             string[] pairs = query.Split(new char[] { '&' });
31             if (pairs != null && pairs.Length > 0)
32             {
33                 foreach (string pair in pairs)
34                 {
35                     string[] oneParam = pair.Split(new char[] { '=' }, 2);
36                     if (oneParam != null && oneParam.Length == 2)
37                     {
38                         result.Add(oneParam[0], oneParam[1]);
39                     }
40                 }
41             }
42
43             return result;
44         }
45     }

  
Step 6

这个验证码有了,就好像有了进当当系统的通行证了,现在我们拿着通行证到当当里把订单信息取出来,代码如下:








1         public void GetOrder()
2         {
3                 string getorderdetail = "gShopID=商家编号&o=&productID=&oit=&os=&sm=&pm=&sendMode=&name=&lastModifyTime_start=&"
4                   + "lastModifyTime_end=&osd=&oed=&sgsd=&sged=&ol=&pageSize=&p=&validateString=";
5                 IDictionary<string, string> Idiction = SplitUrlQuery(getorderdetail);
6                 string serverUrl = "http://api.dangdang.com/v2/searchOrders.php?" + getorderdetail;
7                 string validateString = SignTopRequest(Idiction, "密钥");
8                 string xmlContent = Get(serverUrl + validateString);
9  
10                 ds = XmlToData.CXmlToDataSet(@xmlContent);
11      
12                 dsall.Merge(ds);
13   
14             }
15         }
  Step7

上面这段代码,有个方法就是将XML文件转化成DATASET,这个方法也是我从百度搜来的,懒的自己写了。如下:(你建一个类,类名XmlToData,把这些代码放进去即可)








1 public class XmlToData
2     {
3         public static DataSet CXmlToDataSet(string xmlStr)
4         {
5             if (!string.IsNullOrEmpty(xmlStr))
6             {
7                 StringReader StrStream = null;
8                 XmlTextReader Xmlrdr = null;
9                 try
10                 {
11                     DataSet ds = new DataSet();
12                     StrStream = new StringReader(xmlStr);
13                     Xmlrdr = new XmlTextReader(StrStream);              
14                     ds.ReadXml(Xmlrdr);
15                     return ds;
16                 }
17                 catch (Exception e)
18                 {
19                     throw e;
20                 }
21                 finally
22                 {
23                     if (Xmlrdr != null)
24                     {
25                         Xmlrdr.Close();
26                         StrStream.Close();
27                         StrStream.Dispose();
28                     }
29                 }
30             }
31             else
32             {
33                 return null;
34             }
35         }
36     }
  

Step8
如果你按照上面讲的,操作无误的话,设断点,点调试,在DS里就能看到20条订单列表信息了。当当不会那么容易让你一下取很多数据的,默认的就是20条,且1分钟只能请求30次。拿到这个简单的订单列表信息后,你还需要通过订单编号和通行证,再去取一次该订单的详细信息。这第7步,我来说怎么把VS和SAP打通。

首先你得这样:using SAP.Middleware.Connector;

然后这样,直接上代码:





1         #region 通过NCO3.0将数据写入SAP(ZDDHEADER)
2         public void SAP_DANGDANG_RFC(DataSet dsall)
3         {
4             //读取配置文件信息,建立与SAP连接
5             RfcDestination SapRfcDestination = RfcDestinationManager.GetDestination("DEV");
6             try
7             {
8                 RfcRepository SapRfcRepository = SapRfcDestination.Repository;
9                 IRfcFunction myfun = SapRfcRepository.CreateFunction("ZDANGDANG_RFC_HEADER");
10
11                 // Set some input values for the structure.
12                 IRfcStructure import = null;
13                 IRfcTable table = myfun.GetTable("IT_ZDDHEADER");
14
15                 for (int i = 0; i < dsall.Tables[3].Rows.Count; i++)
16                 {
17                     import = SapRfcRepository.GetStructureMetadata("ZDDHEADER").CreateStructure();
18                     import.SetValue("DD1", dsall.Tables[3].Rows[0].ToString());    //订单编号
19                     import.SetValue("DD21", dsall.Tables[3].Rows[1].ToString());   //收货人姓名
20                     import.SetValue("DD28", dsall.Tables[3].Rows[2].ToString());   //固定电话
21                     import.SetValue("DD29", dsall.Tables[3].Rows[3].ToString());   //手机号码
22                     import.SetValue("DD22", dsall.Tables[3].Rows[4].ToString());   //收货人地址
23                     import.SetValue("DD30", dsall.Tables[3].Rows[5].ToString());   //送货方式
24                     import.SetValue("DD63", dsall.Tables[3].Rows[7].ToString());   //订单总额
25                     import.SetValue("DD62", dsall.Tables[3].Rows[8].ToString());   //下单时间
26                     import.SetValue("DD7", dsall.Tables[3].Rows[9].ToString());    //最后修改时间
27                     import.SetValue("DD2", dsall.Tables[3].Rows[10].ToString());   //订单状态
28                     import.SetValue("DD5", dsall.Tables[3].Rows[11].ToString());   //备注
29                     import.SetValue("DD6", dsall.Tables[3].Rows[12].ToString());   //标记
30                     table.Insert(import);
31                 }
32                 myfun.Invoke(SapRfcDestination); //执行函数
33             }
34             catch (Exception e)
35             {
36                 MessageBox.Show(e.ToString());
37             }
38             finally
39             {
40                 RfcSessionManager.EndContext(SapRfcDestination);
41                 SapRfcDestination = null;
42             }
43         }
44
45         #endregion

  
Step9
  如果上面都无误的话,点运行。然后到SAP的表里就可以看到20条数据了。

DSC0008.jpg
  关于log4net是什么,怎么用,请看我的下一篇博文:http://blog.iyunv.com/szlaptop/article/details/8561650
  原文:http://blog.iyunv.com/szlaptop/article/details/8560430

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-115663-1-1.html 上篇帖子: SAP GUI Security notice 下篇帖子: 一些有用的SAP技术TCODE(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表