17.2 编组器与反编组器

就如在“简介”中提到的,一个编组器负责将一个对象序列化成 XML,而一个反编组器则将 XML 流反序列化为一个对象。我们将在本节对 Spring 提供的两个相关接口进行描述。

17.2.1 编组器

Spring 将所有编组操作抽象成了 org.springframework.oxm.Marshaller 中的方法,以下是该接口最主要的一个方法:

public interface Marshaller {
  /**
    * 将对象编组并存放在 Result 中.
    */
  void marshal(Object graph, Result result) throws XmlMappingException, IOException;
}

Marshaller 接口有一个主方法用于将一个给定对象编组为一个给定的 javax.xml.transform.Result 实现。这里的 Result 是一个用于代表某种 XML 输出格式的标记接口:不同的 Result 实现会封装不同的 XML 表现形式,详见下表:

Result 的实现 封装的 XML 表现形式
DOMResult org.w3c.dom.Node
SAXResult org.xml.sax.ContentHandler
StreamResult java.io.File, java.io.OutputStream, or java.io.Writer

尽管 marshal() 方法的第一个参数只是一个简单对象,但大多数 Marshaller 实现并不真的能处理任意类型的对象。要么这个对象必须在映射文件中定义过映射关系,要么被注解所修饰,要么在编组器中进行过注册,要么与编组器实现拥有共同的基类。参考后面的章节来确定你所选用的 O/X 技术实现具体是怎么做的。

17.2.2 反编组器

与 Marshaller 接口相对应,还有一个 org.springframework.oxm.Unmarshaller 接口。

public interface Unmarshaller {
   /**
     *  将来源 XML 反编组成一个对象
     */
   Object unmarshal(Source source) throws XmlMappingException, IOException;
}

此接口同样也有一个方法,从 javax.xml.transform.Source (一个抽象的 XML 输入)读取 XML 数据,并返回一个相对应的 Java 对象。和 Result 接口一样,Source 是一个拥有三个具体实现的标记接口。每一个实现封装了一种 XML 表现形式。详见下表:

Source 的实现 封装的 XML 表现形式
DOMSource org.w3c.dom.Node
SAXSource org.xml.sax.InputSource, and org.xml.sax.XMLReader
StreamSource java.io.File, java.io.OutputStream, or java.io.Writer

17.2.3 XmlMappingException

Spring 对来自底层 O/X 映射工具的异常进行了转换,以 XmlMappingException 的形式使之成为 Spring 自身异常继承体系的一部分。 这些 Spring 运行时异常将初始异常封装其中,因此所有异常信息都会被完整地保留下来。 额外地,虽然底层的 O/X 映射工具并未提供支持,但 MarshallingFailureException 和 UnmarshallingFailureException 让编组与反编组操作中产生的异常得以能够被区分开来。 The O/X Mapping exception hierarchy is shown in the following figure:

以下是 O/X 映射异常的继承层次: