Android HTTP数据格式的解析
发布日期:2021-11-12 07:57:36 浏览次数:27 分类:技术文章

本文共 12840 字,大约阅读时间需要 42 分钟。

原文地址:http://blog.csdn.net/aqi00/article/details/50655502

json解析

android有两种主流的json解析方案,一种是sdk自带的由Google提供的json(包名前缀为org.json),另一种是Alibaba提供的第三方jar包fastjson(包名前缀为com.alibaba.fastjson)。

json

json的常用方法有:
JSONObject构造函数 : 从指定字符串构造出一个JSONObject对象
JSONObject.getJSONObject : 获取指定名称的JSONObject对象
JSONObject.getString : 获取指定名称的字符串值
JSONObject.put : 添加一个json元素
JSONObject.toString : 把当前JSONObject输出为一个json字符串
JSONObject.getJSONArray : 获取指定名称的json对象数组
JSONArray.length : 获取json对象数组的大小
JSONArray.getJSONObject : 获取json对象数组在指定位置处的JSONObject对象
JSONArray.put : 往json对象数组中添加一个JSONObject对象

fastjson

fastjson的常用方法有:
JSONObject.parseObject : 静态函数,由指定字符串解析出一个JSONObject对象
JSONObject.getJSONObject : 获取指定名称的JSONObject对象
JSONObject.getString : 获取指定名称的字符串值
JSONObject.put : 添加一个json元素
JSONObject.toString : 把当前JSONObject输出为一个json字符串
JSONObject.getJSONArray : 获取指定名称的json对象数组
JSONArray.size : 获取json对象数组的大小
JSONArray.getJSONObject : 获取json对象数组在指定位置处的JSONObject对象
JSONArray.add : 往json对象数组中添加一个JSONObject对象
json和fastjson的用法主要有如下区别:
1、从字符串创建一个JSONObject对象,json调用的是JSONObject的parseObject方法;而fastjson调用的是JSONObject的parseObject方法。
2、获取一个JSONArray对象的大小,json调用的是JSONArray的length方法;而fastjson调用的是JSONArray的size方法。
3、往JSONArray中添加一个JSONObject,json调用的是JSONArray的put方法;而fastjson调用的是JSONArray的add方法。

效果图与示例代码

在前面的《》中,介绍了如何根据定位事件获得当前位置的经度和纬度值,可惜定位事件没法知道当前的详细地址。现在我们利用google map的开放api,传入经纬度的数值,成功的话google会返回一个json字符串,通过解析这个json串就能得到具体的地址名称。下面是json解析的效果截图:
下面是json方式的解析和组包代码示例:
[java]
  1. import org.json.JSONArray;  
  2. import org.json.JSONException;  
  3. import org.json.JSONObject;  
  4.   
  5. public class JsonGoogle {  
  6.   
  7.     public static String parserAddress(String jsonString) {  
  8.         String address = "";  
  9.         try {  
  10.             JSONObject obj = new JSONObject(jsonString);  
  11.             JSONArray resultArray = obj.getJSONArray("results");  
  12.             if (resultArray.length() > 0) {  
  13.                 JSONObject resultObj = resultArray.getJSONObject(0);  
  14.                 address = resultObj.getString("formatted_address");  
  15.             }  
  16.         }catch (JSONException e) {  
  17.             e.printStackTrace();  
  18.         }  
  19.         return address;  
  20.     }  
  21.   
  22.     public static String formatTest() {  
  23.         String str = "";  
  24.         JSONObject obj = new JSONObject();  
  25.         try {  
  26.             obj.put("name""address");  
  27.             JSONArray array = new JSONArray();  
  28.             for (int i = 0; i < 3; i++) {  
  29.                 JSONObject item = new JSONObject();  
  30.                 item.put("item""第" + (i + 1) + "个元素");  
  31.                 array.put(item);  
  32.             }  
  33.             obj.put("list", array);  
  34.             obj.put("count", array.length());  
  35.             obj.put("desc""这是测试串");  
  36.             str = obj.toString();  
  37.         } catch (JSONException e) {  
  38.             e.printStackTrace();  
  39.         }  
  40.         return str;  
  41.     }  
  42.   
  43. }  
下面是fastjson方式的解析和组包代码示例:
[java]
  1. import com.alibaba.fastjson.JSONArray;  
  2. import com.alibaba.fastjson.JSONException;  
  3. import com.alibaba.fastjson.JSONObject;  
  4.   
  5. public class JsonAlibaba {  
  6.   
  7.     public static String parserAddress(String jsonString) {  
  8.         String address = "";  
  9.         try {  
  10.             JSONObject obj = JSONObject.parseObject(jsonString);  
  11.             JSONArray resultArray = obj.getJSONArray("results");  
  12.             if (resultArray.size() > 0) {  
  13.                 JSONObject resultObj = resultArray.getJSONObject(0);  
  14.                 address = resultObj.getString("formatted_address");  
  15.             }  
  16.         }catch (JSONException e) {  
  17.             e.printStackTrace();  
  18.         }  
  19.         return address;  
  20.     }  
  21.   
  22.     public static String formatTest() {  
  23.         String str = "";  
  24.         JSONObject obj = new JSONObject();  
  25.         obj.put("name""address");  
  26.         JSONArray array = new JSONArray();  
  27.         for (int i=0; i<3; i++) {  
  28.             JSONObject item = new JSONObject();  
  29.             item.put("item""第"+(i+1)+"个元素");  
  30.             array.add(item);  
  31.         }  
  32.         obj.put("list", array);  
  33.         obj.put("count", array.size());  
  34.         obj.put("desc""这是测试串");  
  35.         str = obj.toString();  
  36.         return str;  
  37.     }  
  38.   
  39. }  

xml解析

xml解析在android上有三种解决方案,一种是android自带的pull,另外两种是行业标准的sax和dom。

pull

pull在解析xml时是边读取边解析,这种处理方式类似sax,同时pull与sax相比,解析更加方便快速,更适合用于移动平台。pull的常见方法都来自于XmlPullParser类,具体如下:
setInput : 设置解析的输入流。
getEventType : 获取当前节点的事件类型。START_DOCUMENT表示解析开始,START_TAG表示一个标记开始,END_TAG表示一个标记结束。
getName : 获取当前节点的名称。
nextText : 获取当前节点的文本。
next : 解析下一个节点。返回值是下一个节点的事件类型。
getAttributeName : 获取当前节点在指定位置的属性名称。
getAttributeValue : 获取当前节点在指定位置的属性值。

sax

sax也是边读取边解析xml,与pull相比,sax在处理上有些繁琐。首先要写个新类继承自DefaultHandler,然后依次实现下面的函数,最后调用SAXParser的parse函数完成解析操作:
startDocument : 表示解析开始
startElement : 表示开始解析某个节点
characters : 表示开始解析某个节点的文本
endElement : 表示完成解析某个节点

dom

dom是先把整个输入流都读取进来,建立好一个完整的节点树,然后由用户去读取指定节点。由于是整个读取,因此在效率上不够高,不建议在移动平台上应用dom。如果想在建树完毕后再遍历所有节点,大致流程为:先调用DocumentBuilder的parse方法设置输入流,获得一个Document对象;然后调用Document对象的getDocumentElement方法,获得根节点的Element对象;接着调用Element对象的getFirstChild方法,获得根节点下面的第一个子节点Node对象,通过getNodeName和getNodeValue可以分别获得节点名称和节点值;调用Node对象的getNextSibling方法,可以获得下一个节点对象,接着处理下一个节点;如果下一个节点对象为空,则表示输入流解析完毕。

效果图与实例代码

下面是xml解析的效果截图:
下面是pull方式的解析代码示例:
[java]
  1. import java.io.StringReader;  
  2. import java.io.StringWriter;  
  3.   
  4. import org.xmlpull.v1.XmlPullParser;  
  5. import org.xmlpull.v1.XmlSerializer;  
  6.   
  7. import android.util.Log;  
  8. import android.util.Xml;  
  9.   
  10. public class XmlPull {  
  11.     private final static String TAG = "XmlPull";  
  12.   
  13.     public static String parser(String src) {  
  14.         String desc = "";  
  15.         boolean bRoot = true;  
  16.         boolean bList = false;  
  17.         StringReader strReader = new StringReader(src);  
  18.         XmlPullParser parser = Xml.newPullParser();  
  19.         try {  
  20.             parser.setInput(strReader);  
  21.             int eventType = parser.getEventType();  
  22.             while (eventType != XmlPullParser.END_DOCUMENT) {  
  23.                 String name = "";  
  24.                 switch (eventType) {  
  25.                 case XmlPullParser.START_DOCUMENT:  
  26.                     bRoot = true;  
  27.                     bList = false;  
  28.                     break;  
  29.                 case XmlPullParser.START_TAG:  
  30.                     name = parser.getName();  
  31.                     if (bRoot == true) {  
  32.                         desc = String.format("%sPull解析的根节点为:%s。其中\n", desc, name);  
  33.                         bRoot = false;  
  34.                         break;  
  35.                     }  
  36.                     if (name.equals("list") == true) {  
  37.                         desc = String.format("%s\t数组%s的元素列表如下\n", desc, name);  
  38.                         bList = true;  
  39.                     } else if (bList == true) {  
  40.                         if (name.equals("item") == true) {  
  41.                             desc = String.format("%s\t\t元素%s的属性名称为:%s,属性值为:%s\n",   
  42.                                     desc, name, parser.getAttributeName(0), parser.getAttributeValue(0));  
  43.                         } else {  
  44.                             desc = String.format("%s\t\t\t节点%s的值为:%s\n",   
  45.                                     desc, name, parser.nextText());  
  46.                         }  
  47.                     } else {  
  48.                         desc = String.format("%s\t节点%s的值为:%s\n", desc, name, parser.nextText());  
  49.                     }  
  50.                     break;  
  51.                 case XmlPullParser.END_TAG:  
  52.                     name = parser.getName();  
  53.                     if (name.equals("list") == true) {  
  54.                         bList = false;  
  55.                     }  
  56.                     break;  
  57.                 }  
  58.                 Log.d(TAG, "eventType="+eventType+", name="+name);  
  59.                 eventType = parser.next();  
  60.             }  
  61.         } catch (Exception e) {  
  62.             e.printStackTrace();  
  63.         }  
  64.         return desc;  
  65.     }  
  66.   
  67.     public static String format() {  
  68.         StringWriter strWriter = new StringWriter();  
  69.         XmlSerializer serializer = Xml.newSerializer();  
  70.         try {  
  71.             serializer.setOutput(strWriter);  
  72.             serializer.startDocument("UTF-8"true);  
  73.             serializer.startTag(null"content");  
  74.   
  75.             serializer.startTag(null"name");  
  76.             serializer.text("address");  
  77.             serializer.endTag(null"name");  
  78.   
  79.             int count = 3;  
  80.             serializer.startTag(null"list");  
  81.             for (int i=0; i<count; i++) {  
  82.                 serializer.startTag(null"item");  
  83.                 serializer.attribute(null"id", i+"");  
  84.                   
  85.                 serializer.startTag(null"value");  
  86.                 String value = "第" + (i + 1) + "个元素";  
  87.                 serializer.text(value);  
  88.                 serializer.endTag(null"value");  
  89.                   
  90.                 serializer.endTag(null"item");  
  91.             }  
  92.             serializer.endTag(null"list");  
  93.   
  94.             serializer.startTag(null"count");  
  95.             serializer.text(count+"");  
  96.             serializer.endTag(null"count");  
  97.   
  98.             serializer.startTag(null"desc");  
  99.             serializer.text("这是Pull构造的XML测试串");  
  100.             serializer.endTag(null"desc");  
  101.   
  102.             serializer.endTag(null"content");  
  103.             serializer.endDocument();  
  104.         } catch (Exception e) {  
  105.             e.printStackTrace();  
  106.         }  
  107.         return strWriter.toString();  
  108.     }  
  109.   
  110. }  
下面是sax方式的解析代码示例:
[java]
  1. import java.io.ByteArrayInputStream;  
  2. import java.io.InputStream;  
  3.   
  4. import javax.xml.parsers.SAXParser;  
  5. import javax.xml.parsers.SAXParserFactory;  
  6.   
  7. import org.xml.sax.Attributes;  
  8. import org.xml.sax.SAXException;  
  9. import org.xml.sax.helpers.DefaultHandler;  
  10.   
  11. public class XmlSax extends DefaultHandler {  
  12.     private String desc = "";  
  13.     private boolean bRoot = true;  
  14.     private boolean bList = false;  
  15.     private String mTag = "";  
  16.       
  17.     public String toString() {  
  18.         return desc;  
  19.     }  
  20.       
  21.     @Override  
  22.     public void startDocument() throws SAXException {  
  23.         bRoot = true;  
  24.         bList = false;  
  25.     }  
  26.       
  27.     @Override  
  28.     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {  
  29.         if (bRoot == true) {  
  30.             desc = String.format("%sSax解析的根节点为:%s。其中\n", desc, localName);  
  31.             bRoot = false;  
  32.         }  
  33.         if (localName.equals("list") == true) {  
  34.             desc = String.format("%s\t数组%s的元素列表如下\n", desc, localName);  
  35.             bList = true;  
  36.         } else if (bList == true) {  
  37.             if (localName.equals("item") == true) {  
  38.                 desc = String.format("%s\t\t元素%s的属性名称为:%s,属性值为:%s\n",   
  39.                         desc, localName, attributes.getLocalName(0), attributes.getValue(0));  
  40.             }  
  41.         }  
  42.         mTag = localName;  
  43.     }  
  44.       
  45.     @Override  
  46.     public void characters(char[] ch, int start, int length) throws SAXException {  
  47.         if (mTag!=null && mTag.length()>0) {  
  48.             String value = new String(ch , start , length);  
  49.             if (bList == true) {  
  50.                 desc = String.format("%s\t\t\t节点%s的值为:%s\n",   
  51.                         desc, mTag, value);  
  52.             } else {  
  53.                 desc = String.format("%s\t节点%s的值为:%s\n", desc, mTag, value);  
  54.             }  
  55.         }  
  56.     }  
  57.       
  58.     @Override  
  59.     public void endElement(String uri, String localName, String qName) throws SAXException {  
  60.         if (localName.equals("list") == true) {  
  61.             bList = false;  
  62.         }  
  63.     }  
  64.       
  65.     public static String parser(String src) {  
  66.         String desc = "";  
  67.         try {  
  68.             SAXParser parser = SAXParserFactory.newInstance().newSAXParser();  
  69.             InputStream inStream = new ByteArrayInputStream(src.getBytes());  
  70.             XmlSax saxParser = new XmlSax();  
  71.             parser.parse(inStream, saxParser);  
  72.             inStream.close();  
  73.             desc = saxParser.toString();  
  74.         } catch (Exception e) {  
  75.             e.printStackTrace();  
  76.         }  
  77.         return desc;  
  78.     }  
  79.       
  80. }  
下面是dom方式的解析代码示例:
[java]
  1. import java.io.ByteArrayInputStream;  
  2. import java.io.InputStream;  
  3.   
  4. import javax.xml.parsers.DocumentBuilder;  
  5. import javax.xml.parsers.DocumentBuilderFactory;  
  6.   
  7. import org.w3c.dom.Document;  
  8. import org.w3c.dom.Element;  
  9. import org.w3c.dom.NamedNodeMap;  
  10. import org.w3c.dom.Node;  
  11. import org.w3c.dom.NodeList;  
  12.   
  13. public class XmlDom {  
  14.   
  15.     public static String parser(String src) {  
  16.         String desc = "";  
  17.         InputStream inStream = new ByteArrayInputStream(src.getBytes());  
  18.         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
  19.         try {  
  20.             DocumentBuilder builder = factory.newDocumentBuilder();  
  21.             Document document = builder.parse(inStream);  
  22.             Element root = document.getDocumentElement();  
  23.             desc = String.format("%sDom解析的根节点为:%s。其中\n", desc, root.getTagName());  
  24.             Node node = root.getFirstChild();  
  25.             do {  
  26.                 String node_name = node.getNodeName();  
  27.                 if (node_name.equals("list") != true) {  
  28.                     desc = String.format("%s\t节点%s的值为:%s\n", desc, node_name, node.getFirstChild().getNodeValue());  
  29.                 } else {  
  30.                     desc = String.format("%s\t数组%s的元素列表如下\n", desc, node_name);  
  31.                     NodeList itemList = root.getElementsByTagName("item");  
  32.                     for (int i=0; i<itemList.getLength(); i++) {  
  33.                         Node item = itemList.item(i);  
  34.                         if (item.getNodeType() == Node.ELEMENT_NODE) {  
  35.                             NamedNodeMap attr_map = item.getAttributes();  
  36.                             Node attr = attr_map.item(0);  
  37.                             desc = String.format("%s\t\t元素%s的属性名称为:%s,属性值为:%s\n",   
  38.                                     desc, item.getNodeName(), attr.getNodeName(), attr.getNodeValue());  
  39.                             Node item_node = item.getFirstChild();  
  40.                             do {  
  41.                                 desc = String.format("%s\t\t\t节点%s的值为:%s\n",   
  42.                                         desc, item_node.getNodeName(), item_node.getFirstChild().getNodeValue());  
  43.                                 item_node = item_node.getNextSibling();  
  44.                             } while (item_node != null);  
  45.                         }  
  46.                     }  
  47.                 }  
  48.                 node = node.getNextSibling();  
  49.             } while (node != null);  
  50.         } catch (Exception e) {  
  51.             e.printStackTrace();  
  52.         }  
  53.         return desc;  
  54.     }  
  55.       
  56. }  

html解析

android解析html网页可使用开源库jsoup,把jsoup-1.8.1.jar加入到工程的libs目录,即可在工程中调用jsoup的解析方法。
jsoup的解析分为三个层次,第一级是Document,表示整个html网页;第二级是Element,表示某个组件及其下面的元素;第三级是Node,表示某个具体的节点。下面介绍这三个层级的主要用法:
Document:它由Jsoup类的parse函数解析而来,解析的来源可以是字符串String,也可以是文件File,也可以是输入流InputStream,还可以是网址Url。另外,Document继承自Element,因此拥有Element的所有方法;
Element:可由Document先select再get获取某个名称的组件得到。下面是Element的常用方法:
——select : 获取指定名称的组件数组Elements,获取具体的Element可再调用Elements的get方法;
——text : 获取当前组件下的所有文本。不同节点的文本以空格连接。
——attr : 获取指定属性名称的属性值。
Node:虽然Element继承自Node,但是一般Element就够用了,所以Node用得不多。
下面是jsoup解析html的示例代码:
[java]
  1. import java.util.ArrayList;  
  2.   
  3. import org.jsoup.Jsoup;  
  4. import org.jsoup.nodes.Document;  
  5. import org.jsoup.nodes.Element;  
  6.   
  7. import com.example.exmparser.adapter.NoticeItem;  
  8.   
  9. public class HtmlJsoup {  
  10.   
  11.     public static ArrayList<NoticeItem> parser(String content) {  
  12.         ArrayList<NoticeItem> notice_list = new ArrayList<NoticeItem>();  
  13.         Document doc = Jsoup.parse(content);  
  14.         Element link_tr_e = null;  
  15.         for (int i = 0;; i++) {  
  16.             try {  
  17.                 link_tr_e = doc.select("tr").get(i);  
  18.                 String link_tr_s = link_tr_e.text();  
  19.                 if (link_tr_s.length() < 20) {  
  20.                     continue;  
  21.                 }  
  22.             } catch (IndexOutOfBoundsException ex) {  
  23.                 break;  
  24.             }  
  25.             Element link_td_e = null;  
  26.             NoticeItem notice = new NoticeItem();  
  27.             for (int j=0;; j++) {  
  28.                 try {  
  29.                     link_td_e = link_tr_e.select("td").get(j);  
  30.                 } catch (IndexOutOfBoundsException ex) {  
  31.                     break;  
  32.                 }  
  33.                 if (link_td_e.attr("class").equals("list") == true) {  
  34.                     Element link_a_e = link_td_e.select("a").get(0);  
  35.                     notice.title = link_a_e.attr("title");  
  36.                     notice.url = link_a_e.attr("href");  
  37.                 } else if (link_td_e.attr("class").equals("time") == true) {  
  38.                     notice.date = link_td_e.text().replace("(""").replace(")""")  
  39.                             .replace("(""").replace(")""");  
  40.                 }  
  41.             }  
  42.             if (notice.url.equals("") != true) {  
  43.                 notice_list.add(notice);  
  44.             }  
  45.         }  
  46. //      Log.d(TAG, "notice_list.size()=" + notice_list.size());  
  47. //      Log.d(TAG, "");  
  48. //      for (int i = 0; i < notice_list.size(); i++) {
      
  49. //          Log.d(TAG, "公告标题=" + notice_list.get(i).title);  
  50. //          Log.d(TAG, "访问链接=" + notice_list.get(i).url);  
  51. //          Log.d(TAG, "发布日期=" + notice_list.get(i).date);  
  52. //          Log.d(TAG, "");  
  53. //      }  
  54.         return notice_list;  
  55.     }  
  56.   

转载地址:https://blog.csdn.net/happy_love1990/article/details/77471350 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:android:descendantFocusability用法简析
下一篇:Android 定时器AlarmManager

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年03月26日 07时06分58秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

syslog打印不带等级_(转)syslog日志等级 2019-04-21
librosa能量_librosa语音信号处理 2019-04-21
android日期选择区间控件_Android时间区间的选择 2019-04-21
lin通讯从节点同步间隔场_LIN模块介绍 2019-04-21
mysql注入提取邮件_Mysql提取数据每日自动邮件通知 2019-04-21
mysql 列权限_mysql 权限相关 2019-04-21
手机端 vue+vant datetime支持时分秒_vueCli4+vant+router+vuex+移动端适配 2019-04-21
kafka消费者直接存在mysql中_【Canal】利用canal实现mysql实时增量备份并对接kafka 2019-04-21
python中readlines()函数_python中读取文件函数read()、readline()、readlines()的区别 2019-04-21
python入门之基础语法第四关输入输出答案_Python基本语法入门,基础 2019-04-21
mysql在存储过程仍_mysql存储过程 2019-04-21
失败的人生图片_早安励志经典语录精辟的一句话人生感悟 2019-04-21
如何设画面大小_如何设计旅游类项目?分享3种设计思路 2019-04-21
开启web_2021秋招四大网申时间、网申地址汇总(持续更新),德勤、安永、普华永道已开启!... 2019-04-21
从右边开始放_停路边,被人恶意放钉子,爆胎,报警无果,要我找监控 2019-04-21
读写测试_UFS 3.0读写测试数据曝光:秒杀UFS 2.1和eMMC 2019-04-21
注册小程序要多少钱_开发一个微信小程序商城要多少钱? 2019-04-21
mysql 实现id自增序列_MySQL分表自增ID解决方案 2019-04-21
反距离加权插值法例题_空间插值算法-反距离加权法 2019-04-21
oracle如何写循环日期自增_Oracle动态创建时间分区,以及Oracle12c中快速创建自增列... 2019-04-21