1、 什么是XML

XML(Extensible Markup Language 可扩展标记语言) , XML是一个以文本来描述数据的
文档

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <people>
  3. <person personid="E01">
  4. <name>Tony</name>
  5. <address>10 Downing Street, London, UK</address>
  6. <tel>(061) 98765</tel>
  7. <fax>(061) 98765</fax>
  8. <email>tony@everywhere.com</email>
  9. </person>
  10. <person personid="E02">
  11. <name>Bill</name>
  12. <address>White House, USA</address>
  13. <tel>(001) 6400 98765</tel>
  14. <fax>(001) 6400 98765</fax>
  15. <email>bill@everywhere.com</email>
  16. </person>
  17. </people>
  1. package com.vince.xml;
  2. /**
  3. */
  4. public class Person {
  5. private String personid;
  6. private String name;
  7. private String address;
  8. private String tel;
  9. private String fax;
  10. private String email;
  11. @Override
  12. public String toString() {
  13. return "Person{" +
  14. "personid='" + personid + '\'' +
  15. ", name='" + name + '\'' +
  16. ", address='" + address + '\'' +
  17. ", tel='" + tel + '\'' +
  18. ", fax='" + fax + '\'' +
  19. ", email='" + email + '\'' +
  20. '}';
  21. }
  22. public String getPersonid() {
  23. return personid;
  24. }
  25. public void setPersonid(String personid) {
  26. this.personid = personid;
  27. }
  28. public String getName() {
  29. return name;
  30. }
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34. public String getAddress() {
  35. return address;
  36. }
  37. public void setAddress(String address) {
  38. this.address = address;
  39. }
  40. public String getTel() {
  41. return tel;
  42. }
  43. public void setTel(String tel) {
  44. this.tel = tel;
  45. }
  46. public String getFax() {
  47. return fax;
  48. }
  49. public void setFax(String fax) {
  50. this.fax = fax;
  51. }
  52. public String getEmail() {
  53. return email;
  54. }
  55. public void setEmail(String email) {
  56. this.email = email;
  57. }
  58. }

2、 XML的用途

XML技术的用途:

(1) 充当显示数据(以XML充当显示层)
(2) 存储数据(存储层) 的功能
(3) 以XML描述数据, 并在联系服务器与系统的其余部分之间传递。 (传输数据的一样格式)

从某种角度讲, XML是数据封装和消息传递技术


3、 SAX解析XML

SAX是Simple API for XML的缩写

SAX 是读取和操作 XML 数据更快速、 更轻量的方法。 SAX 允许您在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。 它不涉及 DOM 所必需的开销和概念跳跃。 SAX API是一个基于事件的API , 适用于处理数据流, 即随着数据的流动而依次处理数据。 SAX API 在其解析您的文档时发生一定事件的时候会通知您。 在您对其响应时,您不作保存的数据将会被抛弃

SAX API中主要有四种处理事件的接口, 它们分别是ContentHandler, DTDHandler,EntityResolver 和 ErrorHandler 。

实际上只要继承DefaultHandler 类就可以,
DefaultHandler实现了这四个事件处理器接口, 然后提供了每个抽象方法的默认实现。

  1. // 创建SAX解析器工厂对象
  2. SAXParserFactory spf = SAXParserFactory.newInstance();
  3. // 使用解析器工厂创建解析器实例
  4. SAXParser saxParser = spf.newSAXParser();
  5. // 创建SAX解析器要使用的事件侦听器对象
  6. PersonHandler handler =new PersonHandler();
  7. // 开始解析文件
  8. saxParser.parse(new File(fileName), handler);

XMLDemo for SAX

  1. package com.vince.xml;
  2. import org.jdom2.Element;
  3. import org.jdom2.JDOMException;
  4. import org.jdom2.input.SAXBuilder;
  5. import org.junit.Test;
  6. import org.w3c.dom.Document;
  7. import org.w3c.dom.Node;
  8. import org.w3c.dom.NodeList;
  9. import org.xml.sax.SAXException;
  10. import javax.xml.parsers.*;
  11. import java.io.*;
  12. import java.util.ArrayList;
  13. import java.util.Arrays;
  14. import java.util.List;
  15. /**
  16. */
  17. public class XMLDemo {
  18. /**
  19. * SAX解析的特点:
  20. * 1、基于事件驱动
  21. * 2、顺序读取,速度快
  22. * 3、不能任意读取节点(灵活性差)
  23. * 4、解析时占用的内存小
  24. * 5、SAX更适用于在性能要求更高的设备上使用(Android开发中)
  25. * @throws ParserConfigurationException
  26. * @throws SAXException
  27. * @throws IOException
  28. */
  29. @Test
  30. public void saxParseXML() throws ParserConfigurationException, SAXException, IOException {
  31. //1、创建一个SAX解析器工厂对象
  32. SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
  33. //2、通过工厂对象创建SAX解析器
  34. SAXParser saxParser = saxParserFactory.newSAXParser();
  35. //3、创建一个数据处理器(需要我们自己来编写)
  36. PersonHandler personHandler = new PersonHandler();
  37. //4、开始解析
  38. InputStream is = Thread.currentThread().getContextClassLoader()
  39. .getResourceAsStream("com/vince/xml/person.xml");
  40. saxParser.parse(is,personHandler);
  41. List<Person> persons = personHandler.getPersons();
  42. for (Person p:persons){
  43. System.out.println(p);
  44. }
  45. }
  46. }

PersonHandler

  1. package com.vince.xml;
  2. import org.xml.sax.Attributes;
  3. import org.xml.sax.SAXException;
  4. import org.xml.sax.helpers.DefaultHandler;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. /**
  8. * Created by vince on 2017/7/1.
  9. * SAX解析的特点:
  10. * 1、基于事件驱动
  11. * 2、顺序读取,速度快
  12. * 3、不能任意读取节点(灵活性差)
  13. * 4、解析时占用的内存小
  14. * 5、SAX更适用于在性能要求更高的设备上使用(Android开发中)
  15. *
  16. */
  17. public class PersonHandler extends DefaultHandler{
  18. private List<Person> persons = null;
  19. private Person p;//当前正在解析的person
  20. private String tag;//用于记录当前正在解析的标签名
  21. public List<Person> getPersons() {
  22. return persons;
  23. }
  24. //开始解析文档时调用
  25. @Override
  26. public void startDocument() throws SAXException {
  27. super.startDocument();
  28. persons = new ArrayList<>();
  29. System.out.println("开始解析文档...");
  30. }
  31. //在XML文档解析结束时调用
  32. @Override
  33. public void endDocument() throws SAXException {
  34. super.endDocument();
  35. System.out.println("解析文档结束.");
  36. }
  37. /**
  38. * 解析开始元素时调用
  39. * @param uri 命名空间
  40. * @param localName 不带前缀的标签名
  41. * @param qName 带前缀的标签名
  42. * @param attributes 当前标签的属性集合
  43. * @throws SAXException
  44. */
  45. @Override
  46. public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  47. super.startElement(uri, localName, qName, attributes);
  48. if ("person".equals(qName)){
  49. p = new Person();
  50. String personid = attributes.getValue("personid");
  51. p.setPersonid(personid);
  52. }
  53. tag = qName;
  54. System.out.println("startElement--"+qName);
  55. }
  56. //解析结束元素时调用
  57. @Override
  58. public void endElement(String uri, String localName, String qName) throws SAXException {
  59. super.endElement(uri, localName, qName);
  60. if ("person".equals(qName)) {
  61. persons.add(p);
  62. }
  63. tag = null;
  64. System.out.println("endElement--"+qName);
  65. }
  66. //解析文本内容时调用
  67. @Override
  68. public void characters(char[] ch, int start, int length) throws SAXException {
  69. super.characters(ch, start, length);
  70. if (tag != null) {
  71. if ("name".equals(tag)) {
  72. p.setName(new String(ch,start,length));
  73. }else if("address".equals(tag)){
  74. p.setAddress(new String(ch,start,length));
  75. }else if("tel".equals(tag)){
  76. p.setTel(new String(ch,start,length));
  77. }else if("fax".equals(tag)){
  78. p.setFax(new String(ch,start,length));
  79. }else if("email".equals(tag)){
  80. p.setEmail(new String(ch,start,length));
  81. }
  82. System.out.println(ch);
  83. }
  84. }
  85. }

4、 DOM解析XML

JAVA 解析 XML 通常有两种方式, DOM 和 SAX

DOM: Document Object Model(文档对象模型)

DOM的特性:

定义一组 Java 接口, 基于对象, 与语言和平台无关将 XML 文档表示为树, 在内存中解析和存储 XML 文档, 允许随机访问文档的不同部分。

DOM解析XML:

DOM的优点, 由于树在内存中是持久的, 因此可以修改后更新。 它还可以在任何时候在树中上下导航, API使用起来也较简单。

解析步骤:

  1. DocumentBuilderFactory builder = DocumentBuilderFactory.newInstance();
  2. DocumentBuilder db = builder.newDocumentBuilder();
  3. db.parse("person.xml");
  4. NodeList node_person = doc.getElementsByTagName("person");
  1. /**
  2. * DOM解析XML
  3. * 1、基于树型结构,通过解析器一次性把文档加载到内存中,所以会比较占用内存,可以随机访问
  4. * 更加灵活,更适合在WEB开发中使用
  5. */
  6. @Test
  7. public void domParseXML() throws ParserConfigurationException, IOException, SAXException {
  8. //1、创建一个DOM解析器工厂对象
  9. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  10. //2、通过工厂对象创建解析器对象
  11. DocumentBuilder documentBuilder = factory.newDocumentBuilder();
  12. //3、解析文档
  13. InputStream is = Thread.currentThread().getContextClassLoader()
  14. .getResourceAsStream("com/vince/xml/person.xml");
  15. //此代码完成后,整个XML文档已经被加载到内存中,以树状形式存储
  16. Document doc = documentBuilder.parse(is);
  17. //4、从内存中读取数据
  18. //获取节点名称为person的所有节点,返回节点集合
  19. NodeList personNodeList = doc.getElementsByTagName("person");
  20. ArrayList<Person> persons = new ArrayList<>();
  21. Person p = null;
  22. //此循环会迭代两次
  23. for (int i=0;i<personNodeList.getLength();i++){
  24. Node personNode = personNodeList.item(i);
  25. p = new Person();
  26. //获取节点的属性值
  27. String personid = personNode.getAttributes().getNamedItem("personid").getNodeValue();
  28. p.setPersonid(personid);
  29. //获取当前节点的所有子节点
  30. NodeList childNodes = personNode.getChildNodes();
  31. for (int j = 0;j<childNodes.getLength();j++){
  32. Node item = childNodes.item(j);
  33. String nodeName = item.getNodeName();
  34. if ("name".equals(nodeName)) {
  35. p.setName(item.getFirstChild().getNodeValue());
  36. }else if("address".equals(nodeName)){
  37. p.setAddress(item.getFirstChild().getNodeValue());
  38. }else if("tel".equals(nodeName)){
  39. p.setTel(item.getFirstChild().getNodeValue());
  40. }else if("fax".equals(nodeName)){
  41. p.setFax(item.getFirstChild().getNodeValue());
  42. }else if("email".equals(nodeName)){
  43. p.setEmail(item.getFirstChild().getNodeValue());
  44. }
  45. }
  46. persons.add(p);
  47. }
  48. System.out.println("结果:");
  49. System.out.println(Arrays.toString(persons.toArray()));
  50. }

5、 JDOM解析XML

JDOM是两位著名的 Java 开发人员兼作者, Brett Mclaughlin 和 Jason Hunter 的创作成果,2000 年初在类似于Apache协议的许可下, JDOM作为一个开放源代码项目正式开始研发了。

JDOM 简化了与 XML 的交互并且比使用 DOM 实现更快, JDOM 与 DOM 主要有两方面不同。 首先, JDOM 仅使用具体类而不使用接口。 这在某些方面简化了 API, 但是也限制了灵活性。 第二, API 大量使用了 Collections 类, 简化了那些已经熟悉这些类的 Java开发者的使用。

下载地址:
http://www.jdom.org/downloads/index.html

解析步骤:
(1) SAXBuilder sax = new SAXBuilder();
(2) Document doc = sax.build(….);
(3) Element el = doc.getRootElement();
(4) List list = el.getChildren();
(5) 遍历内容

  1. /**
  2. * JDOM解析 XML
  3. * 1、与DOM类似基于树型结构,
  4. * 2、与DOM的区别:
  5. * (1)第三方开源的组件
  6. * (2)实现使用JAVA的Collection接口
  7. * (3)效率比DOM更快
  8. */
  9. @Test
  10. public void jdomParseXML() throws JDOMException, IOException {
  11. //创建JDOM解析器
  12. SAXBuilder builder = new SAXBuilder();
  13. InputStream is = Thread.currentThread().getContextClassLoader()
  14. .getResourceAsStream("com/vince/xml/person.xml");
  15. org.jdom2.Document build = builder.build(is);
  16. Element rootElement = build.getRootElement();
  17. List<Person> list = new ArrayList<>();
  18. Person person = null;
  19. List<Element> children = rootElement.getChildren();
  20. for(Element element: children){
  21. person = new Person();
  22. String personid = element.getAttributeValue("personid");
  23. person.setPersonid(personid);
  24. List<Element> children1 = element.getChildren();
  25. for (Element e: children1){
  26. String tag = e.getName();
  27. if("name".equals(tag)){
  28. person.setName(e.getText());
  29. }else if("address".equals(tag)){
  30. person.setAddress(e.getText());
  31. }else if("tel".equals(tag)){
  32. person.setTel(e.getText());
  33. }else if("fax".equals(tag)){
  34. person.setFax(e.getText());
  35. }else if("email".equals(tag)){
  36. person.setEmail(e.getText());
  37. }
  38. }
  39. list.add(person);
  40. }
  41. System.out.println("结果:");
  42. System.out.println(Arrays.toString(list.toArray()));
  43. }

6、 DOM4J解析XML

dom4j是一个非常非常优秀的Java XML API, 具有性能优异、 功能强大和极端易用使用的特点, 同时它也是一个开放源代码的软件, 可以在SourceForge上找到它。 在对主流的Java XML API进行的性能、 功能和易用性的评测, dom4j无论在那个方面都是非常出色的。 如今你可以看到越来越多的Java软件都在使用dom4j来读写XML, 特别值得一提的是连Sun的JAXM也在用dom4j。 这是必须使用的jar包, Hibernate用它来读写配置文件。

下载地址:
https://dom4j.github.io/

解析步骤:
(1) SAXReader sax = new SAXReader();
(2) Document doc = sax.read(Thread.currentThread().getContextClassLoader().getResourceAsStream(“person.xml”));
(3) Element root = doc.getRootElement();
(4) Iterator iterator = root.elementIterator();
(5) 遍历迭代器

  1. /**
  2. * DOM4J解析XML
  3. * 基于树型结构,第三方组件
  4. * 解析速度快,效率更高,使用的JAVA中的迭代器实现数据读取,在WEB框架中使用较多(Hibernate)
  5. *
  6. */
  7. @Test
  8. public void dom4jParseXML() throws DocumentException {
  9. //1 创建DOM4J的解析器对象
  10. SAXReader reader = new SAXReader();
  11. InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/xml/person.xml");
  12. org.dom4j.Document doc = reader.read(is);
  13. org.dom4j.Element rootElement = doc.getRootElement();
  14. Iterator<org.dom4j.Element> iterator = rootElement.elementIterator();
  15. ArrayList<Person> persons = new ArrayList<>();
  16. Person p = null;
  17. while(iterator.hasNext()){
  18. p = new Person();
  19. org.dom4j.Element e = iterator.next();
  20. p.setPersonid(e.attributeValue("personid"));
  21. Iterator<org.dom4j.Element> iterator1 = e.elementIterator();
  22. while(iterator1.hasNext()){
  23. org.dom4j.Element next = iterator1.next();
  24. String tag = next.getName();
  25. if("name".equals(tag)){
  26. p.setName(next.getText());
  27. }else if("address".equals(tag)){
  28. p.setAddress(next.getText());
  29. }else if("tel".equals(tag)){
  30. p.setTel(next.getText());
  31. }else if("fax".equals(tag)){
  32. p.setFax(next.getText());
  33. }else if("email".equals(tag)){
  34. p.setEmail(next.getText());
  35. }
  36. }
  37. persons.add(p);
  38. }
  39. System.out.println("结果:");
  40. System.out.println(Arrays.toString(persons.toArray()));
  41. }

7、 通过对象生成XML文件

.
使用Java提供的java.beans.XMLEncoder和java.beans.XMLDecoder类。
这是JDK 1.4以后才出现的类
步骤:
(1) 实例化XML编码器
XMLEncoder xmlEncoder = new XMLEncoder(new BufferedOutputStream(newFileOutputStream(new File(“a.xml”))));
(2) 输出对象
(3) 关闭

  1. /**
  2. * 从XML文件中读取对象
  3. */
  4. @Test
  5. public void xmlDecoder() throws FileNotFoundException {
  6. BufferedInputStream in = new BufferedInputStream(new FileInputStream("test.xml"));
  7. XMLDecoder decoder = new XMLDecoder(in);
  8. Person p = (Person)decoder.readObject();
  9. System.out.println(p);
  10. }
  11. /**
  12. * 把对象转成XML文件写入
  13. */
  14. @Test
  15. public void xmlEncoder() throws FileNotFoundException {
  16. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.xml"));
  17. XMLEncoder xmlEncoder = new XMLEncoder(bos);
  18. Person p = new Person();
  19. p.setPersonid("1212");
  20. p.setAddress("北京");
  21. p.setEmail("vince@163.com");
  22. p.setFax("6768789798");
  23. p.setTel("13838389438");
  24. p.setName("38");
  25. xmlEncoder.writeObject(p);
  26. xmlEncoder.close();
  27. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <java version="1.8.0_77" class="java.beans.XMLDecoder">
  3. <object class="com.vince.xml.Person">
  4. <void property="address">
  5. <string>北京</string>
  6. </void>
  7. <void property="email">
  8. <string>vince@163.com</string>
  9. </void>
  10. <void property="fax">
  11. <string>6768789798</string>
  12. </void>
  13. <void property="name">
  14. <string>38</string>
  15. </void>
  16. <void property="personid">
  17. <string>1212</string>
  18. </void>
  19. <void property="tel">
  20. <string>13838389438</string>
  21. </void>
  22. </object>
  23. </java>

8、 各种解析方法比较

JDOM 和 DOM 在性能测试时表现不佳, 在测试 10M 文档时内存溢出。

SAX表现较好, 这要依赖于它特定的解析方式。 一个 SAX 检测即将到来的XML流, 但并没有载入到内存(当然当XML流被读入时, 会有部分文档暂时隐藏在内存中)。

DOM4J是这场测试的获胜者, 目前许多开源项目中大量采用 DOM4J, 例如大名鼎鼎的Hibernate 也用 DOM4J 来读取 XML 配置文件。

xstream 实现XML的转换

  1. /**
  2. * 使用第三方xstream组件实现XML的解析与生成
  3. */
  4. @Test
  5. public void xStream(){
  6. Person p = new Person();
  7. p.setPersonid("1212");
  8. p.setAddress("北京");
  9. p.setEmail("vince@163.com");
  10. p.setFax("6768789798");
  11. p.setTel("13838389438");
  12. p.setName("38");
  13. XStream xStream = new XStream(new Xpp3Driver());
  14. xStream.alias("person",Person.class);
  15. xStream.useAttributeFor(Person.class,"personid");
  16. String xml = xStream.toXML(p);
  17. System.out.println(xml);
  18. //解析XML
  19. Person person = (Person)xStream.fromXML(xml);
  20. System.out.println(person);
  21. }

17、XML与Json - 图1


9、Json

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 JSON 官方:http://www.json.org
JSON 数据格式的特点

JSON 建构于两种结构:
1、 “ 名称/值” 对的集合
2.、 值的有序列表(数组)

JSON 表示名称 / 值对的方式 :

  1. { "firstName": "vince", "lastName":"ma", "email":"finally_m@foxmail.com" }

表示数组

  1. { "user": [{ "firstName": "vince", "lastName":"ma", "email": "finally_m@foxmail.com" },{ "firstName": "lin", "lastName":"jacks", "email":“ jacks@qq.com }]}

10、 GSON组件的使用

GSON是Google开发的Java API, 用于转换Java对象和Json对象。

下载地址: http://www.mvnrepository.com/artifact/com.google.code.gson/gson

解析JSON: JsonReader reader = new JsonReader(new StringReader(jsonData));

生成JSON:

  1. private String createJSON(ArrayList<User> users) {
  2. JSONObject jsonObject = new JSONObject();JSONArray array = new JSONArray();
  3. int size = users.size();
  4. try {
  5. for (int i = 0; i < size; i++) {
  6. User user = users.get(i); JSONObject object = new JSONObject();
  7. object.put("name", user.name);object.put("age", user.age);array.put(object);
  8. }
  9. jsonObject.put("users",array);
  10. return jsonObject.toString();
  11. } catch (JSONException e) {
  12. e.printStackTrace();
  13. }
  14. return null;
  15. }
  16. static class User {String name; int age;//…}

JsonDemo1

  1. package com.vince.json;
  2. import com.google.gson.stream.JsonReader;
  3. import org.junit.Test;
  4. import javax.print.attribute.standard.MediaSize;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.InputStreamReader;
  8. import java.util.ArrayList;
  9. import java.util.Arrays;
  10. /**
  11. * Created by vince on 2017/7/1.
  12. */
  13. public class JSONDemo {
  14. /**
  15. * 解析一个JSON数组
  16. */
  17. @Test
  18. public void parseJSONNames(){
  19. InputStream is = Thread.currentThread().getContextClassLoader()
  20. .getResourceAsStream("com/vince/json/names.json");
  21. InputStreamReader in = new InputStreamReader(is);
  22. //JSON的解析工具(解析器)
  23. JsonReader reader = new JsonReader(in);
  24. ArrayList<Name> list = new ArrayList<>();
  25. try {
  26. //开始解析数组
  27. reader.beginArray();
  28. while(reader.hasNext()){
  29. list.add(parseName(reader));
  30. }
  31. //结束解析数组
  32. reader.endArray();
  33. } catch (IOException e) {
  34. e.printStackTrace();
  35. }
  36. System.out.println(Arrays.toString(list.toArray()));
  37. }
  38. //解析对象 Name
  39. private Name parseName(JsonReader jsonReader){
  40. Name name = null;
  41. try {
  42. //开始解析对象
  43. jsonReader.beginObject();
  44. name = new Name();
  45. while (jsonReader.hasNext()){
  46. String attrName = jsonReader.nextName();
  47. if("firstName".equals(attrName)){
  48. name.setFirstName(jsonReader.nextString());
  49. }else if("lastName".equals(attrName)){
  50. name.setLastName(jsonReader.nextString());
  51. }else if("email".equals(attrName)){
  52. name.setEmail(jsonReader.nextString());
  53. }
  54. }
  55. //结束解析对象
  56. jsonReader.endObject();
  57. } catch (IOException e) {
  58. e.printStackTrace();
  59. }
  60. return name;
  61. }
  62. }

Names.json

  1. [
  2. {"firstName":"Vince","lastName":"Ma","email":"1791705739@qq.com"},
  3. {"firstName":"Jason","lastName":"Hunter","email":"jason@google.com"}
  4. ]

比较复杂的一个例子:

message.json

  1. [
  2. {
  3. "id": 912345678901,
  4. "text": "How do I read a JSON stream in Java?",
  5. "geo": null,
  6. "user": {
  7. "name": "json_newb",
  8. "followers_count": 41
  9. }
  10. },
  11. {
  12. "id": 912345678902,
  13. "text": "@json_newb just use JsonReader!",
  14. "geo": [50.454722, -104.606667],
  15. "user": {
  16. "name": "jesse",
  17. "followers_count": 2
  18. }
  19. }
  20. ]

JsonDemo2

方法虽多,但一层套一层,结构思路清晰

  1. package com.vince.json;
  2. import com.google.gson.stream.JsonReader;
  3. import com.google.gson.stream.JsonToken;
  4. import org.junit.Test;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.InputStreamReader;
  8. import java.util.ArrayList;
  9. /**
  10. * Created by vince on 2017/7/1.
  11. */
  12. public class JsonDemo2 {
  13. /**
  14. * 使用JsonReader解析复杂的JSON数据
  15. */
  16. @Test
  17. public void parseJSONMessages(){
  18. InputStream is = Thread.currentThread().getContextClassLoader()
  19. .getResourceAsStream("com/vince/json/message.json");
  20. InputStreamReader in = new InputStreamReader(is);
  21. JsonReader jsonReader = new JsonReader(in);
  22. ArrayList<Message> list = readMessageArray(jsonReader);
  23. for (Message m: list){
  24. System.out.println(m);
  25. }
  26. }
  27. //读取Message数组
  28. private ArrayList<Message> readMessageArray(JsonReader jsonReader) {
  29. ArrayList<Message> list = new ArrayList<>();
  30. try {
  31. jsonReader.beginArray();
  32. while(jsonReader.hasNext()){
  33. list.add(readMessage(jsonReader));
  34. }
  35. jsonReader.endArray();
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. return list;
  40. }
  41. //解析一个Message对象
  42. private Message readMessage(JsonReader jsonReader) {
  43. Message m = new Message();
  44. try {
  45. jsonReader.beginObject();
  46. while (jsonReader.hasNext()){
  47. String name = jsonReader.nextName();
  48. if("id".equals(name)){
  49. m.setId(jsonReader.nextLong());
  50. }else if("text".equals(name)){
  51. m.setText(jsonReader.nextString());
  52. }else if("geo".equals(name) && jsonReader.peek()!= JsonToken.NULL){
  53. m.setGeo(readGeo(jsonReader));
  54. }else if("user".equals(name)){
  55. m.setUser(readUser(jsonReader));
  56. }else{
  57. jsonReader.skipValue();
  58. }
  59. }
  60. jsonReader.endObject();
  61. } catch (IOException e) {
  62. e.printStackTrace();
  63. }
  64. return m;
  65. }
  66. /**
  67. * 解析User对象
  68. * @param jsonReader
  69. * @return
  70. */
  71. private User readUser(JsonReader jsonReader) {
  72. User user = new User();
  73. try {
  74. jsonReader.beginObject();
  75. while (jsonReader.hasNext()){
  76. String name = jsonReader.nextName();
  77. if("name".equals(name)){
  78. user.setName(jsonReader.nextString());
  79. }else if("followers_count".equals(name)){
  80. user.setFollowers_count(jsonReader.nextInt());
  81. }else{
  82. jsonReader.skipValue();
  83. }
  84. }
  85. jsonReader.endObject();
  86. } catch (IOException e) {
  87. e.printStackTrace();
  88. }
  89. return user;
  90. }
  91. /**
  92. * 解析GEO
  93. * @param jsonReader
  94. * @return
  95. */
  96. private ArrayList<Double> readGeo(JsonReader jsonReader) {
  97. ArrayList<Double> list = new ArrayList<>();
  98. try {
  99. jsonReader.beginArray();
  100. while (jsonReader.hasNext()){
  101. list.add(jsonReader.nextDouble());
  102. }
  103. jsonReader.endArray();
  104. } catch (IOException e) {
  105. e.printStackTrace();
  106. }
  107. return list;
  108. }
  109. }

使用 Gson 直接把 JSON 数据转换成 Java

  1. public Student parserJSON2(String data){
  2. Gson gson = new Gson();
  3. Student s = gson.fromJson(data, Student.class);
  4. return s;
  5. }

使用 Gson 直接把 JSON 数组转换成 Java 对象

  1. public List<Student> parserJSON3(String data){
  2. Type type = new TypeToken<ArrayList<Student>>(){}.getType();
  3. Gson gson = new Gson();
  4. List<Student> list = gson.fromJson(data, type);
  5. return list;
  6. }
  1. package com.vince.json;
  2. import com.google.gson.Gson;
  3. import com.google.gson.JsonArray;
  4. import com.google.gson.JsonObject;
  5. import com.google.gson.reflect.TypeToken;
  6. import com.google.gson.stream.JsonToken;
  7. import org.junit.Test;
  8. import java.io.InputStream;
  9. import java.io.InputStreamReader;
  10. import java.lang.reflect.Type;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. /**
  14. * Created by vince on 2017/7/1.
  15. */
  16. public class JsonDemo3 {
  17. /**
  18. * 把一组JSON对象转换成一个JAVA对象集合,或者把一个JAVA对象集合转换成JSON数组
  19. */
  20. @Test
  21. public void gson2(){
  22. Gson gson = new Gson();
  23. InputStream is = Thread.currentThread().getContextClassLoader()
  24. .getResourceAsStream("com/vince/json/names.json");
  25. InputStreamReader in = new InputStreamReader(is);
  26. TypeToken<List<Name>> typeToken = new TypeToken<List<Name>>(){};
  27. List<Name> list = gson.fromJson(in, typeToken.getType());
  28. System.out.println(list);
  29. String json = gson.toJson(list, typeToken.getType());
  30. System.out.println(json);
  31. }
  32. class MyTypeToken extends TypeToken<List<Name>>{}
  33. /**
  34. * 把一个JSON对象转换成JAVA对象,或把一个JAVA对象转换成JSON对象
  35. */
  36. @Test
  37. public void gson1(){
  38. Gson gson = new Gson();
  39. InputStream is = Thread.currentThread().getContextClassLoader()
  40. .getResourceAsStream("com/vince/json/name.json");
  41. InputStreamReader in = new InputStreamReader(is);
  42. Name name = gson.fromJson(in, Name.class);
  43. System.out.println(name);
  44. String json = gson.toJson(name);
  45. System.out.println(json);
  46. }
  47. @Test
  48. public void createJSON(){
  49. List<Name> list = new ArrayList<>();
  50. list.add(new Name("vince","ma","1791705739@qq.com"));
  51. list.add(new Name("jack","wang","jack@qq.com"));
  52. JsonArray array = new JsonArray();
  53. for (Name n: list){
  54. JsonObject obj = new JsonObject();
  55. obj.addProperty("firstName",n.getFirstName());
  56. obj.addProperty("lastName",n.getLastName());
  57. obj.addProperty("email",n.getEmail());
  58. array.add(obj);
  59. }
  60. System.out.println(array.toString());
  61. }
  62. }
  1. {"firstName":"Vince","lastName":"Ma","email":"1791705739@qq.com"}

11、 XML与JSON的比较

从以下6点比较JSON与XML:
1、 JSON和XML的数据可读性基本相同
2、 JSON和XML同样拥有丰富的解析手段
3、 JSON相对于XML来讲, 数据的体积小
4、 JSON与JavaScript的交互更加方便
5、 JSON对数据的描述性比XML较差
6、 JSON的速度要远远快于XML

适合的场景:
(1) 数据传输: JSON要比XML更有优势
(2) 存储数据: XML描述性更强
(3) XML通常用做配置文件(WEB课程中会有详细介绍)