XML与JSON

XML(eXtensible Markup Language)

  • 可扩展标记语言,常通过网络作为消息传输

  • 特点

    • 纯文本,默认使用UTF-8编码
    • 可嵌套,适合表示结构化数据
  • 结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE note SYSTEM "book.dtd">
    <book id="1">
    <name>Java核心技术</name>
    <author>Cay S. Horstmann</author>
    <isbn lang="CN">1234567</isbn>
    <tags>
    <tag>Java</tag>
    <tag>Network</tag>
    </tags>
    <pubDate/>
    </book>
    • 第一行固定
    • 第二行声明的是文档定义类型,如(DTD:Document Type Definition),可选。可以指定一系列规则,来验证XML的数据结构,例如:
      • 根元素必须是book
      • book元素必须包含nameauthor等指定元素
      • isbn元素必须包含属性lang
    • 后面是文件内容,特殊符号需转义
  • 和结构类似的HTML不同,浏览器对HTML有一定的“容错性”,缺少关闭标签也可以被解析,但 XML要求严格的格式,任何没有正确嵌套的标签都会导致错误。

  • 除了我们经常用到的XML文档本身外,XML还支持:

    • DTD和XSD:验证XML结构和数据是否有效;
    • Namespace:XML节点和属性的名字空间;
    • XSLT:把XML转化为另一种文本;
    • XPath:一种XML节点查询语言;

解析XML:DOM

XML是一种树形结构的文档,它有两种标准的解析API:

  • DOM:一次性读取XML,并在内存中表示为树形结构;
  • SAX:以流的形式读取XML,使用事件回调。

DOM是Document Object Model的缩写,DOM模型就是把XML结构作为一个 树形结构 处理,从根节点开始,每个节点都可以包含任意个子节点。

Java提供了DOM API来解析XML,它使用下面的对象来表示XML的内容:

  • Document:代表整个XML文档;
  • Element:代表一个XML元素;
  • Attribute:代表一个元素的某个属性。
1
2
3
4
5
InputStream input = Main.class.getResourceAsStream("/book.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(input); // 用于解析一个XML,它可以接收InputStream,File或者URL
// 返回Document对象,这个对象代表了整个XML文档的树形结构

可以遍历结点获取指定元素值[1]

DOM解析速度慢,内存占用大。

解析XML:SAX

SAX是Simple API for XML的缩写,它是一种基于流的解析方式, 边读取XML边解析 ,并以 事件回调 的方式让调用者获取数据。因为是一边读一边解析,所以无论XML有多大,占用的内存都很小。

SAX解析会触发一系列事件:

  • startDocument:开始读取XML文档;
  • startElement:读取到了一个元素,例如<book>
  • characters:读取到了字符;
  • endElement:读取到了一个结束的元素,例如</book>
  • endDocument:读取XML文档结束。

用SAX API解析XML

1
2
3
4
InputStream input = Main.class.getResourceAsStream("/book.xml");
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(input, new MyHandler()); // 回调对象MuHandler,继承自DefaultHandler

调用方必须通过回调方法获得解析过程中的数据。

解析XML:Jackson

把XML文档解析成一个JavaBean[2]

json

XML的特点是功能全面,但标签繁琐,格式复杂。

JSON是JavaScript Object Notation的缩写,它去除了所有JavaScript执行代码,只保留JavaScript的对象格式。

优点:

  • JSON只允许使用UTF-8编码,不存在编码问题;
  • JSON只允许使用双引号作为key,特殊字符用\转义,格式简单;
  • 浏览器内置JSON支持,如果把数据用JSON发送给浏览器,可以用JavaScript直接处理。

因此,JSON适合表示层次结构,因为它格式简单,仅支持以下几种数据类型:

  • 键值对:{"key": value}
  • 数组:[1, 2, 3]
  • 字符串:"abc"
  • 数值(整数和浮点数):12.34
  • 布尔值:truefalse
  • 空值:null

绝大多数REST API都选择JSON作为数据传输格式。

使用jackson解析JSON

引入以下Maven依赖:

  • com.fasterxml.jackson.core:jackson-databind:2.12.0

把JSON解析为JavaBean的过程称为 反序列化 。如果把JavaBean变为JSON,那就是 序列化

1
2
3
4
5
6
7
InputStream input = Main.class.getResourceAsStream("/book.json");
ObjectMapper mapper = new ObjectMapper();
// 反序列化时忽略不存在的JavaBean属性:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Book book = mapper.readValue(input, Book.class);
// 序列化
String json = mapper.writeValueAsString(book);

可以通过Module扩展Jackson能处理的数据类型;

可以自定义JsonSerializerJsonDeserializer来定制序列化和反序列化。

JDBC编程

Java为 关系数据库 定义了一套标准的访问接口:JDBC(Java Database Connectivity)

使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现真正对数据库的访问。

通过JDBC接口来访问,这样保证了Java程序编写的是一套数据库访问代码,却可以访问各种不同的数据库,因为他们都提供了标准的JDBC驱动:

image-20220308234109650

SQL (Structured Query Language) 是具有数据操纵和数据定义等多种功能的数据库语言,这种语言具有交互性特点[3]

NoSQL: 非SQL的数据库,包括MongoDB、Cassandra、Dynamo等等[4]

NoSQL框架体系NosoL整体框架分为四层,由下至上分为:[5]

  • 数据持久层(data persistence): 定义了数据的存储形式,主要包括基于内存、基于硬盘、内存和硬盘接口、订制可拔插四种形
  • 整体分布层(data distribution model): 定义了数据是如何分布
    • CAP支持: 可用于水平扩展
    • 多数据中心支持: 可以保证在横跨多数据中心是也能够平稳运行
    • 动态部署支持: 可以在运行着的集群中动态地添加或删除节点
  • 数据逻辑模型层(data logical model): 键值模型、列式模型、文档模型、图模型
  • 接口层(interface): Rest,Thrift,Map/Reduce,Get/Put,特定语言API

  1. 使用DOM - 廖雪峰的官方网站 (liaoxuefeng.com) ↩︎

  2. 使用Jackson - 廖雪峰的官方网站 (liaoxuefeng.com) ↩︎

  3. SQL数据库_百度百科 (baidu.com) ↩︎

  4. SQL教程 - 廖雪峰的官方网站 (liaoxuefeng.com) ↩︎

  5. NoSQL_百度百科 (baidu.com) ↩︎