概述:
项目包含Android端+Web后台端,使用到了Handler ,多线程, Apache Http编程 ,XML+JSON文件的6种解析方式,是个不错的学习案例。
JAR包和项目下载地址在最后面。
1、Web端
1、JSON字符串
2、XML文件
2、Android端
一、什么是JSON?
JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度。
JSON就是一串字符串 只不过元素会使用特定的符号标注。
{} 双括号表示对象
[] 中括号表示数组
"" 双引号内是属性或值
: 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象)
所以 {"name": "Michael"} 可以理解为是一个包含name为Michael的对象
而[{"name": "Michael"},{"name": "Jerry"}]就表示包含两个对象的数组
当然了,你也可以使用{"name":["Michael","Jerry"]}来简化上面一部,这是一个拥有一个name数组的对象
二、传统的JSON
1、生成JSON字符串
[java] view plain copy print ?
- <span style="font-size:14px;">public static String createJsonString(String key, Object value) {
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(key, value);
- return jsonObject.toString();
- }</span>
<span style="font-size:14px;">public static String createJsonString(String key, Object value) {
JSONObject jsonObject = new JSONObject();
jsonObject.put(key, value);
return jsonObject.toString();
}</span>
2、解析JSON字符串
分为以下三种情况,一个JavaBean,一个List数组,一个嵌套Map的List数组:
[java] view plain copy print ?
- <span style="font-size:14px;">import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
-
- import org.json.JSONArray;
- import org.json.JSONObject;
-
- import com.android.myjson.domain.Person;
-
-
-
-
-
- public class JsonTools {
-
-
- public static Person getPerson(String key, String jsonString) {
- Person person = new Person();
- try {
- JSONObject jsonObject = new JSONObject(jsonString);
- JSONObject personObject = jsonObject.getJSONObject("person");
- person.setId(personObject.getInt("id"));
- person.setName(personObject.getString("name"));
- person.setAddress(personObject.getString("address"));
- } catch (Exception e) {
-
- }
- return person;
- }
-
- public static List<Person> getPersons(String key, String jsonString) {
- List<Person> list = new ArrayList<Person>();
- try {
- JSONObject jsonObject = new JSONObject(jsonString);
-
- JSONArray jsonArray = jsonObject.getJSONArray(key);
- for (int i = 0; i < jsonArray.length(); i++) {
- JSONObject jsonObject2 = jsonArray.getJSONObject(i);
- Person person = new Person();
- person.setId(jsonObject2.getInt("id"));
- person.setName(jsonObject2.getString("name"));
- person.setAddress(jsonObject2.getString("address"));
- list.add(person);
- }
- } catch (Exception e) {
-
- }
- return list;
- }
-
- public static List<String> getList(String key, String jsonString) {
- List<String> list = new ArrayList<String>();
- try {
- JSONObject jsonObject = new JSONObject(jsonString);
- JSONArray jsonArray = jsonObject.getJSONArray(key);
- for (int i = 0; i < jsonArray.length(); i++) {
- String msg = jsonArray.getString(i);
- list.add(msg);
- }
- } catch (Exception e) {
-
- }
- return list;
- }
-
- public static List<Map<String, Object>> listKeyMaps(String key,
- String jsonString) {
- List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
- try {
- JSONObject jsonObject = new JSONObject(jsonString);
- JSONArray jsonArray = jsonObject.getJSONArray(key);
- for (int i = 0; i < jsonArray.length(); i++) {
- JSONObject jsonObject2 = jsonArray.getJSONObject(i);
- Map<String, Object> map = new HashMap<String, Object>();
- Iterator<String> iterator = jsonObject2.keys();
- while (iterator.hasNext()) {
- String json_key = iterator.next();
- Object json_value = jsonObject2.get(json_key);
- if (json_value == null) {
- json_value = "";
- }
- map.put(json_key, json_value);
- }
- list.add(map);
- }
- } catch (Exception e) {
-
- }
- return list;
- }
- }</span>
<span style="font-size:14px;">import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import com.android.myjson.domain.Person;
/**
* 完成对json数据的解析
*
*/
public class JsonTools {
public static Person getPerson(String key, String jsonString) {
Person person = new Person();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONObject personObject = jsonObject.getJSONObject("person");
person.setId(personObject.getInt("id"));
person.setName(personObject.getString("name"));
person.setAddress(personObject.getString("address"));
} catch (Exception e) {
// TODO: handle exception
}
return person;
}
public static List<Person> getPersons(String key, String jsonString) {
List<Person> list = new ArrayList<Person>();
try {
JSONObject jsonObject = new JSONObject(jsonString);
// 返回json的数组
JSONArray jsonArray = jsonObject.getJSONArray(key);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject2 = jsonArray.getJSONObject(i);
Person person = new Person();
person.setId(jsonObject2.getInt("id"));
person.setName(jsonObject2.getString("name"));
person.setAddress(jsonObject2.getString("address"));
list.add(person);
}
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
public static List<String> getList(String key, String jsonString) {
List<String> list = new ArrayList<String>();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray(key);
for (int i = 0; i < jsonArray.length(); i++) {
String msg = jsonArray.getString(i);
list.add(msg);
}
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
public static List<Map<String, Object>> listKeyMaps(String key,
String jsonString) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray(key);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject2 = jsonArray.getJSONObject(i);
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> iterator = jsonObject2.keys();
while (iterator.hasNext()) {
String json_key = iterator.next();
Object json_value = jsonObject2.get(json_key);
if (json_value == null) {
json_value = "";
}
map.put(json_key, json_value);
}
list.add(map);
}
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
}</span>
三、GSON
1、生成JSON字符串
[java] view plain copy print ?
- <span style="font-size:14px;">import com.google.gson.Gson;
-
- public class JsonUtils {
-
- public static String createJsonObject(Object obj) {
- Gson gson = new Gson();
- String str = gson.toJson(obj);
- return str;
-
- }
- }</span>
<span style="font-size:14px;">import com.google.gson.Gson;
public class JsonUtils {
public static String createJsonObject(Object obj) {
Gson gson = new Gson();
String str = gson.toJson(obj);
return str;
}
}</span>
二、解析JSON
[java] view plain copy print ?
- <span style="font-size:14px;">import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
-
- import com.google.gson.Gson;
- import com.google.gson.reflect.TypeToken;
-
- ;
- public class GsonTools {
-
- public GsonTools() {
-
- }
-
-
-
-
-
-
-
- public static <T> T getPerson(String jsonString, Class<T> cls) {
- T t = null;
- try {
- Gson gson = new Gson();
- t = gson.fromJson(jsonString, cls);
- } catch (Exception e) {
-
- }
- return t;
- }
-
-
-
-
-
-
-
-
-
- public static <T> List<T> getPersons(String jsonString, Class<T> cls) {
- List<T> list = new ArrayList<T>();
- try {
- Gson gson = new Gson();
- list = gson.fromJson(jsonString, new TypeToken<List<Person.class>>() {
- }.getType());
- } catch (Exception e) {
- }
- return list;
- }
-
-
-
-
-
- public static List<String> getList(String jsonString) {
- List<String> list = new ArrayList<String>();
- try {
- Gson gson = new Gson();
- list = gson.fromJson(jsonString, new TypeToken<List<String>>() {
- }.getType());
- } catch (Exception e) {
-
- }
- return list;
- }
-
- public static List<Map<String, Object>> listKeyMaps(String jsonString) {
- List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
- try {
- Gson gson = new Gson();
- list = gson.fromJson(jsonString,
- new TypeToken<List<Map<String, Object>>>() {
- }.getType());
- } catch (Exception e) {
-
- }
- return list;
- }
- }</span>
<span style="font-size:14px;">import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
;
public class GsonTools {
public GsonTools() {
// TODO Auto-generated constructor stub
}
/**
* @param <T>
* @param jsonString
* @param cls
* @return
*/
public static <T> T getPerson(String jsonString, Class<T> cls) {
T t = null;
try {
Gson gson = new Gson();
t = gson.fromJson(jsonString, cls);
} catch (Exception e) {
// TODO: handle exception
}
return t;
}
/**
* 使用Gson进行解析 List<Person>
*
* @param <T>
* @param jsonString
* @param cls
* @return
*/
public static <T> List<T> getPersons(String jsonString, Class<T> cls) {
List<T> list = new ArrayList<T>();
try {
Gson gson = new Gson();
list = gson.fromJson(jsonString, new TypeToken<List<Person.class>>() {
}.getType());
} catch (Exception e) {
}
return list;
}
/**
* @param jsonString
* @return
*/
public static List<String> getList(String jsonString) {
List<String> list = new ArrayList<String>();
try {
Gson gson = new Gson();
list = gson.fromJson(jsonString, new TypeToken<List<String>>() {
}.getType());
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
public static List<Map<String, Object>> listKeyMaps(String jsonString) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
try {
Gson gson = new Gson();
list = gson.fromJson(jsonString,
new TypeToken<List<Map<String, Object>>>() {
}.getType());
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
}</span>
四、FastJSON
[java] view plain copy print ?
- <span style="font-size:14px;">import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
-
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.TypeReference;
-
- public class JsonTool {
-
- public static <T> T getPerson(String jsonstring, Class<T> cls) {
- T t = null;
- try {
- t = JSON.parseObject(jsonstring, cls);
- } catch (Exception e) {
-
- }
- return t;
- }
-
- public static <T> List<T> getPersonList(String jsonstring, Class<T> cls) {
- List<T> list = new ArrayList<T>();
- try {
- list = JSON.parseArray(jsonstring, cls);
- } catch (Exception e) {
-
- }
- return list;
- }
-
- public static <T> List<Map<String, Object>> getPersonListMap1(
- String jsonstring) {
- List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
- try {
- list = JSON.parseObject(jsonstring,
- new TypeReference<List<Map<String, Object>>>() {
- }.getType());
-
- } catch (Exception e) {
-
- }
-
- return list;
- }
- }</span>
<span style="font-size:14px;">import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
public class JsonTool {
public static <T> T getPerson(String jsonstring, Class<T> cls) {
T t = null;
try {
t = JSON.parseObject(jsonstring, cls);
} catch (Exception e) {
// TODO: handle exception
}
return t;
}
public static <T> List<T> getPersonList(String jsonstring, Class<T> cls) {
List<T> list = new ArrayList<T>();
try {
list = JSON.parseArray(jsonstring, cls);
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
public static <T> List<Map<String, Object>> getPersonListMap1(
String jsonstring) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
try {
list = JSON.parseObject(jsonstring,
new TypeReference<List<Map<String, Object>>>() {
}.getType());
} catch (Exception e) {
// TODO: handle exception
}
return list;
}
}</span>
总结:
JSON对于移动设备来说,尤其对于网络环境较差和流量限制的情况下,相对于XML格式的数据传输会更节省流量,传输效率更高。在这三种解析方式中FastJson是效率最高的,推荐使用。
XML解析
XML为一种可扩展的标记语言,是一种简单的数据存储语言,使用一系列简单的标记来描述。
一、SAX解析
即Simple API for XML,以事件的形式通知程序,对Xml进行解析。
1、首先在Web项目中发布一个XML文档,名字为persons.xml,具体内容为:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="1">
<name>周杰伦</name>
<age>20</age>
</person>
<person id="2">
<name>小明</name>
<age>21</age>
</person>
</persons>
2、SAX解析的流程主要如下:
通过创建SAXParserFactory对象获得一个实例,然后再通过工厂获得一个SaxParser,依靠SaxParser的parse方法,完成解析,其中parse方法的参数为一个InputStream类和一个DefaultHandler类,defaultHandler需 要重写
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parse = spf.newSAXParser();
Myhandler handler = new Myhandler("person");
parse.parse(is, handler);
list = handler.getList();
3、重写处理类DefaultHandler。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class Myhandler extends DefaultHandler {
List<HashMap<String, String>> list = null;// 存储所有的解析对象
String currentTag = null; // 正在解析的标签
String currentValue = null; // 正在解析元素的值
String nodename = null; // 正在解析节点名称
HashMap<String, String> map = null;// 存储单个解析的完整对象
public Myhandler(String nodename) {
this.nodename = nodename;
}
public List<HashMap<String, String>> getList() {
return list;
}
@Override
// 读到第一个开始标签的时候触发
public void startDocument() throws SAXException {
list = new ArrayList<HashMap<String, String>>();
}
@Override
// 当遇到所要解析的节点名称时触发
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals(nodename)) {
map = new HashMap<String, String>();
}
if (attributes != null && map != null) {
for (int i = 0; i < attributes.getLength(); i++) {
map.put(attributes.getQName(i), attributes.getValue(i));
}
}
currentTag = qName;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equals(nodename)) {
list.add(map);
map = null;
}
super.endElement(uri, localName, qName);
}
@Override
// 处理xml文件读取到的内容
public void characters(char[] ch, int start, int length)
throws SAXException {
if (currentTag != null && map != null) {
currentValue = new String(ch, start, length);
if (currentValue != null && !currentValue.trim().equals("")
&& !currentValue.trim().equals("\n")) {
map.put(currentTag, currentValue);
}
}
currentTag = null;
currentValue = null;
}
}
4、通过自定义的HttpUtils类,从服务器获取数据,以流的形式返回,也就是XML文档的输入流,这里不再给出,关于获得服务器数据的三种方式下次会下次更新。
5、最后通过返回的List<Map<String,String>> 获得了XML文档的所需要的内容,需要提到的是,我在这里是需要解析person节点,于是只有qName等于person时候才会开始解析。
二、PULL解析
类似于SAX方式,程序以“拉取”的方式对Xml进行解析。
1、与SAX解析类似,但比SAX解析容易
2、首先通过XMLPullFactory创建一个工厂,然后再由工厂创建一个XMLPullParser对象,由对象进行相关处理。
3、通过对eventType进行XML文件的节点解析,获得数据,并存放在List中进行返回。
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class PullXmlHandler {
public static List<Person> parseXml(InputStream is, String encode)
throws Exception {
List<Person> list = null;
Person p = null;
try {
XmlPullParserFactory xmlPullF = XmlPullParserFactory.newInstance();
XmlPullParser parser = xmlPullF.newPullParser();
parser.setInput(is, encode);
int eventType = parser.getEventType();
//如果还没到文档结束节点就一直循环
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
list = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if (parser.getName().equals("person")) {
p = new Person();
if (parser.getAttributeCount() != 0) {
p.setId(parser.getAttributeValue(0));
}
} else if (parser.getName().equals("name")) {
p.setName(parser.nextText());
} else if (parser.getName().equals("age")) {
p.setAge(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals("person")) {
list.add(p);
p = null;
}
break;
default:
break;
}
//进行下次循环
eventType = parser.next();
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
}
三、DOM解析
“文档对象模型”方式,解析完的Xml将生成一个树状结构的对象。
1、DOM解析相对前两种比较麻烦,代码如下:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.xml.httputils.http_post;
public class DomService {
public DomService() {
}
public static List<Person> parseXML(InputStream is) throws Exception {
List<Person> list = new ArrayList<Person>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
// 获得节点
Element element = document.getDocumentElement();
NodeList nodeList = element.getElementsByTagName("person");
for (int i = 0; i < nodeList.getLength(); i++) {
Element personElement = (Element) nodeList.item(i);
Person p = new Person();
p.setId(personElement.getAttribute("id"));
NodeList personList = personElement.getChildNodes();
for (int j = 0; j < personList.getLength(); j++) {
if (personList.item(j).getNodeType() == Node.ELEMENT_NODE) {
if ("name".equals(personList.item(j).getNodeName())) {
p.setName(personList.item(j).getFirstChild()
.getNodeValue());
} else if ("age".equals(personList.item(j).getNodeName())) {
p.setAge(personList.item(j).getFirstChild()
.getNodeValue());
}
}
}
list.add(p);
}
return list;
}
public static void main(String[] args) throws Exception {
DomService dom = new DomService();
List<Person> ps = dom.parseXML(http_post.getXMLStream());
for (Person p : ps) {
System.out.println(p);
}
}
}
总结:
对于小内存的设备,尤其是Android设备,使用PULL解析或者SAX解析远优于DOM解析。