使用XStream解析XML(使用淘宝开放API服务)
2010-11-07 21:48
302 查看
本文意在简单说明XStream解析XML,配合淘宝的开放API,那么我们在电子商务模式的系统中就可以使用一些淘宝API来为系统增加一个与众不同的模块。
首先来看淘宝API,这是本应用的重要部分,淘宝API的手册可以在线查看:下面就来说说简单的流程。我们通过URL发出请求,并收到返回的结果(XML或JSON)。请求中包含了一些必须的参数,这个就是文档中说明的。这里我们使用淘宝的商品API,获取一些商品的信息。在这之前需要在开放平台注册,获取你自己的APP_KEY和APP_SECRET,很简单。
获取到必要信息后,我们来看一下URL请求,这个需要符合TAOBAO的要求,才能请求到数据,其中有一段信息是加密的,就是签名字段,这个字段的计算比较复杂,网站提供的方法好像已经不能用了,那么我根据TAOBAO提供的SDK源码自行提取有用部分来编写了一个简单的算法。首先我们来看一下测试应用的结构:
使用Maven对应用进行管理,因为只是简单的应用程序,所以配置很简单,引入的第三方依赖也不多,我们来看看都需要些什么:
加入了这些依赖之后,我们就可以进行开发了。看了之前的代码结构,我们先从请求TAOBAO的数据开始说。就是生成请求签名的类SinguratureGenerator.java来看:
我们使用的是MD5的加密算法,需要传入一个TreeMap类型的参数集合对象,还有就是申请到的APP_SECRET字符串。使用TreeMap主要是利用其按照参数名的字典顺序排序特性,这也是TAOBAO的API要求的,那么算法注释很清楚了,这也是对它的SDK的简化,只保留必要内容。下面就是请求TAOBAO-API的类了,里面拼凑了请求参数并获得返回的结果:
至此我们已经可以获得返回的XML数据,其中封装了商品信息,剩下的就是解析商品信息了,TAOBAO对商品信息定义了数据结构,我们按照这个结构封装对象,之后结合XStream来解析XML就获得了我们想要的数据了,那么先看商品数据结构,这里仅获取几个简单的供示例演示使用:
这里封装了整体的响应结果,item是商品的数据结构,如下:
这里我们只要三个信息:卖家名称,商品价格,商品所在地,而所在地又是一个封装的数据结果对象,简单示例如下:
获取省份和城市,这些数据结构的完整信息就要参考API文档了,这里仅仅是示例。下面就可以运行测试类了:
XStream的使用很简单,将XML中的标签和对象进行别名绑定,之后读取XML并根据标签的层级进行数据填充,之后我们就可以按照预先定于的对象进行数据获取了,这里为了保护测试的卖家信息,将ID中最后两位隐藏,运行测试类,就得到如下的信息了:
首先来看淘宝API,这是本应用的重要部分,淘宝API的手册可以在线查看:下面就来说说简单的流程。我们通过URL发出请求,并收到返回的结果(XML或JSON)。请求中包含了一些必须的参数,这个就是文档中说明的。这里我们使用淘宝的商品API,获取一些商品的信息。在这之前需要在开放平台注册,获取你自己的APP_KEY和APP_SECRET,很简单。
获取到必要信息后,我们来看一下URL请求,这个需要符合TAOBAO的要求,才能请求到数据,其中有一段信息是加密的,就是签名字段,这个字段的计算比较复杂,网站提供的方法好像已经不能用了,那么我根据TAOBAO提供的SDK源码自行提取有用部分来编写了一个简单的算法。首先我们来看一下测试应用的结构:
使用Maven对应用进行管理,因为只是简单的应用程序,所以配置很简单,引入的第三方依赖也不多,我们来看看都需要些什么:
加入了这些依赖之后,我们就可以进行开发了。看了之前的代码结构,我们先从请求TAOBAO的数据开始说。就是生成请求签名的类SinguratureGenerator.java来看:
package taobao.util; import java.security.MessageDigest; import java.util.Set; import java.util.TreeMap; import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; /** * 生成淘宝API中的签名密码 * * @author Nanlei * */ public class SignatureGenerator { /** * 获取MD5加密结果 * * @param params * 参数集合 * @param secret * 申请得到的APP_SECRET * @return */ public static String getMD5Signature(TreeMap<String, String> params, String secret) { // 存储签名的StringBuffer StringBuilder sign = new StringBuilder(); // 获取参数的项集合 Set<Entry<String, String>> paramSet = params.entrySet(); // 组合要编码的串 StringBuilder query = new StringBuilder(secret); // 遍历参数集合,获取参数值,形式key+value for (Entry<String, String> param : paramSet) { if (StringUtils.isNotEmpty(param.getKey()) && StringUtils.isNotEmpty(param.getValue())) { query.append(param.getKey()).append(param.getValue()); } } try { // 使用MD5加密 MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] bytes = md5.digest(query.toString().getBytes("UTF-8")); // 把二进制转化为大写的十六进制 for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() == 1) { sign.append("0"); } sign.append(hex.toUpperCase()); } } catch (Exception e) { throw new java.lang.RuntimeException("Signature Generate Error!"); } return sign.toString(); } }
我们使用的是MD5的加密算法,需要传入一个TreeMap类型的参数集合对象,还有就是申请到的APP_SECRET字符串。使用TreeMap主要是利用其按照参数名的字典顺序排序特性,这也是TAOBAO的API要求的,那么算法注释很清楚了,这也是对它的SDK的简化,只保留必要内容。下面就是请求TAOBAO-API的类了,里面拼凑了请求参数并获得返回的结果:
package taobao; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.TreeMap; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import taobao.util.SignatureGenerator; /** * 获取淘宝API返回的结果 * * @author Nanlei * */ public class GetResult { // 需要的常量参数 private static final String URL = "http://gw.api.taobao.com/router/rest"; private static final String APP_KEY = "请填写你申请的"; private static final String APP_SECRET = "请填写你申请的"; private static final String FORMAT = "xml"; private static final String METHOD = "taobao.item.get"; private static final String VERSION = "2.0"; private static DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * 获取结果的方法 * * @param fields * 需要请求的商品字段 * @param num_iid * 商品ID,淘宝网URL中获得 * @return */ public static String getResult(String fields, String num_iid) { String content = null; HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(URL); String timestamp = getFullTime(); List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("app_key", APP_KEY)); params.add(new BasicNameValuePair("format", FORMAT)); params.add(new BasicNameValuePair("method", METHOD)); params.add(new BasicNameValuePair("num_iid", num_iid)); params.add(new BasicNameValuePair("fields", fields)); params.add(new BasicNameValuePair("timestamp", timestamp)); params.add(new BasicNameValuePair("partner_id", "911")); params.add(new BasicNameValuePair("v", VERSION)); params.add(new BasicNameValuePair("sign", SignatureGenerator .getMD5Signature(getParams(timestamp, fields, num_iid), APP_SECRET))); try { post.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); HttpResponse response = client.execute(post); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_IMPLEMENTED) { System.err .println("The Post Method is not implemented by this URI"); } else { content = EntityUtils.toString(response.getEntity()); } } catch (IOException e) { System.err.println(e); } finally { client.getConnectionManager().shutdown(); } return content; } /** * 拼装参数 * * @param timestamp * 当前时间戳 * @param fields * 需要请求的商品字段 * @param num_iid * 商品ID,淘宝网URL中获得 * @return */ public static TreeMap<String, String> getParams(String timestamp, String fields, String num_iid) { TreeMap<String, String> treeMap = new TreeMap<String, String>(); treeMap.put("timestamp", timestamp); treeMap.put("v", VERSION); treeMap.put("app_key", APP_KEY); treeMap.put("method", METHOD); treeMap.put("partner_id", "911"); treeMap.put("format", FORMAT); treeMap.put("fields", fields); treeMap.put("num_iid", num_iid); return treeMap; } /** * 获取格式化好的时间 * * @return */ public static String getFullTime() { return df.format(new java.util.Date()); } }
至此我们已经可以获得返回的XML数据,其中封装了商品信息,剩下的就是解析商品信息了,TAOBAO对商品信息定义了数据结构,我们按照这个结构封装对象,之后结合XStream来解析XML就获得了我们想要的数据了,那么先看商品数据结构,这里仅获取几个简单的供示例演示使用:
package taobao.bean; public class Response { private Item item; public Item getItem() { return item; } public void setItem(Item item) { this.item = item; } }
这里封装了整体的响应结果,item是商品的数据结构,如下:
package taobao.bean; public class Item { private String nick; private String price; private Location location; public String getNick() { return nick; } public void setNick(String nick) { this.nick = nick; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public Location getLocation() { return location; } public void setLocation(Location location) { this.location = location; } }
这里我们只要三个信息:卖家名称,商品价格,商品所在地,而所在地又是一个封装的数据结果对象,简单示例如下:
package taobao.bean; public class Location { private String state; private String city; public String getState() { return state; } public void setState(String state) { this.state = state; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
获取省份和城市,这些数据结构的完整信息就要参考API文档了,这里仅仅是示例。下面就可以运行测试类了:
package taobao; import taobao.bean.Item; import taobao.bean.Location; import taobao.bean.Response; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; /** * 获取商品信息测试类 * * @author Nanlei * */ public class TaobaoXMLResult { public static void main(String[] args) throws Exception { // 获取的商品ID和需要的字段 String resultXML = GetResult.getResult("price,location,nick", "74222099XX"); // XStream解析XML XStream xstream = new XStream(new DomDriver()); xstream.alias("item_get_response", Response.class); xstream.alias("item", Item.class); xstream.alias("location", Location.class); System.out.println(resultXML); // XML转对象 Response response = (Response) xstream.fromXML(resultXML); Item item = response.getItem(); // 打印结果 System.out.println("省份: " + item.getLocation().getState()); System.out.println("价格: " + item.getPrice()); System.out.println("店铺名称: " + item.getNick()); } }
XStream的使用很简单,将XML中的标签和对象进行别名绑定,之后读取XML并根据标签的层级进行数据填充,之后我们就可以按照预先定于的对象进行数据获取了,这里为了保护测试的卖家信息,将ID中最后两位隐藏,运行测试类,就得到如下的信息了:
相关文章推荐
- XStream的使用方法、简单使用方法、xml的解析方法
- 安卓xml使用第三方框架Xstream解析
- XStream xml 解析框架使用笔记
- 使用jar包XStream解析xml数据
- 使用XStream解析复杂的XML文件
- 使用xstream解析XML转换成带泛型的对象
- android 使用XStream解析xml的实例
- 安卓xml使用第三方框架Xstream解析
- android 使用XStream解析xml
- 使用XStream解析和生成xml文件
- java中解析复杂xml(XStream简单使用)
- 使用第三方框架Xstream轻松解析xml数据
- android中解析复杂xml(XStream简单使用)
- 使用xstream解析xml
- Android中使用XStream解析XML
- java使用Xstream注解 解析xml文件 并将数据导入MySql数据库中
- 使用XStream解析复杂的XML文件
- 解析XML文档之三:使用DOM解析
- 使用XStream是实现XML与Java对象的转换(1)--简介及入门示例
- 使用XStream是实现XML与Java对象的转换(5)--Object Stream