介绍
本章介绍 Spring 的 Object-XML 映射支持。对象 XML 映射(简称 O-X 映射)是将 XML 文档与 XML 文档相互转换的行为 一个对象。此转换过程也称为 XML 封组或 XML 序列化。本章可互换使用这些术语。
在 O-X 映射领域中,编组员负责序列化 对象(图形)转换为 XML。以类似的方式,解编器将 XML 反序列化为 对象图。此 XML 可以采用 DOM 文档、输入或输出的形式 stream 或 SAX 处理程序。
使用 Spring 满足 O/X 映射需求的一些好处是:
易于配置
Spring 的 bean factory 使配置编组器变得容易,而无需 构造 JAXB 上下文、JiBX 绑定工厂等。您可以配置编组器 就像应用程序上下文中的任何其他 Bean 一样。此外,基于 XML 命名空间 配置可用于多个编组器,使配置均匀 简单。
一致的接口
Spring 的 O-X 映射通过两个全局接口运行:Marshaller
和 Unmarshaller
。通过这些抽象,可以切换 O-X 映射框架
相对容易,几乎不需要对执行
编组。这种方法还有一个额外的好处,即可以执行 XML
使用混合和匹配方法进行封送(例如,使用 JAXB 执行的某些封送
还有一些是 XStream)以非侵入性的方式,让您使用每个的力量
科技。
Marshaller
和Unmarshaller
如引言中所述,编组器序列化对象 转换为 XML,然后取消编组程序将 XML 流反序列化为对象。本节介绍 用于此目的的两个 Spring 接口。
理解Marshaller
Spring 抽象了接口后面的所有编组操作,其主要方法如下:org.springframework.oxm.Marshaller
public interface Marshaller {
/**
* Marshal the object graph with the given root into the provided Result.
*/
void marshal(Object graph, Result result) throws XmlMappingException, IOException;
}
该接口有一个 main 方法,该方法将给定对象封送到
鉴于。结果是一个标记界面,基本上
表示 XML 输出抽象。包装各种 XML 的具体实现
表示形式,如下表所示:Marshaller
javax.xml.transform.Result
结果实现 | 包装 XML 表示形式 |
---|---|
|
|
|
|
|
|
尽管该方法接受普通对象作为其第一个参数,但大多数实现无法处理任意对象。相反,对象类
必须映射到映射文件中,用注释标记,并在
编组器,或者具有公共基类。请参阅本章后面的部分
以确定您的 O-X 技术如何管理此问题。marshal() Marshaller |
理解Unmarshaller
与 类似,我们有接口,如下表所示:Marshaller
org.springframework.oxm.Unmarshaller
public interface Unmarshaller {
/**
* Unmarshal the given provided Source into an object graph.
*/
Object unmarshal(Source source) throws XmlMappingException, IOException;
}
此接口还有一个方法,该方法从给定的(XML 输入抽象)读取并返回读取的对象。如
with 是一个标记接口,它有三个具体的实现。每
包装不同的 XML 表示形式,如下表所示:javax.xml.transform.Source
Result
Source
源实现 | 包装 XML 表示形式 |
---|---|
|
|
|
|
|
|
尽管有两个单独的封送接口( 和 ),但 Spring-WS 中的所有实现都在一个类中实现。
这意味着您可以连接一个编组器类,并将其同时称为
编组员和作为 un编组员 在您的 .Marshaller
Unmarshaller
applicationContext.xml
使用 和Marshaller
Unmarshaller
您可以在各种情况下使用 Spring 的 OXM。在下面的例子中,我们 使用它将 Spring 托管应用程序的设置封送为 XML 文件。在下面的例子中,我们 使用简单的 JavaBean 来表示设置:
-
Java
-
Kotlin
public class Settings {
private boolean fooEnabled;
public boolean isFooEnabled() {
return fooEnabled;
}
public void setFooEnabled(boolean fooEnabled) {
this.fooEnabled = fooEnabled;
}
}
class Settings {
var isFooEnabled: Boolean = false
}
应用程序类使用此 Bean 来存储其设置。除了主要方法外,
class 有两种方法:将设置 Bean 保存到名为 的文件中,然后再次加载这些设置。以下方法
构造一个 Spring 应用程序上下文并调用以下两种方法:saveSettings()
settings.xml
loadSettings()
main()
-
Java
-
Kotlin
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
public class Application {
private static final String FILE_NAME = "settings.xml";
private Settings settings = new Settings();
private Marshaller marshaller;
private Unmarshaller unmarshaller;
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
public void saveSettings() throws IOException {
try (FileOutputStream os = new FileOutputStream(FILE_NAME)) {
this.marshaller.marshal(settings, new StreamResult(os));
}
}
public void loadSettings() throws IOException {
try (FileInputStream is = new FileInputStream(FILE_NAME)) {
this.settings = (Settings) this.unmarshaller.unmarshal(new StreamSource(is));
}
}
public static void main(String[] args) throws IOException {
ApplicationContext appContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
Application application = (Application) appContext.getBean("application");
application.saveSettings();
application.loadSettings();
}
}
class Application {
lateinit var marshaller: Marshaller
lateinit var unmarshaller: Unmarshaller
fun saveSettings() {
FileOutputStream(FILE_NAME).use { outputStream -> marshaller.marshal(settings, StreamResult(outputStream)) }
}
fun loadSettings() {
FileInputStream(FILE_NAME).use { inputStream -> settings = unmarshaller.unmarshal(StreamSource(inputStream)) as Settings }
}
}
private const val FILE_NAME = "settings.xml"
fun main(args: Array<String>) {
val appContext = ClassPathXmlApplicationContext("applicationContext.xml")
val application = appContext.getBean("application") as Application
application.saveSettings()
application.loadSettings()
}
需要设置 a 和 an 属性。我们
可以使用以下方法执行此操作:Application
marshaller
unmarshaller
applicationContext.xml
<beans>
<bean id="application" class="Application">
<property name="marshaller" ref="xstreamMarshaller" />
<property name="unmarshaller" ref="xstreamMarshaller" />
</bean>
<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"/>
</beans>
此应用程序上下文使用 XStream,但我们可以使用任何其他编组器
本章稍后将介绍实例。请注意,默认情况下,XStream 不需要
任何进一步的配置,所以 Bean 的定义相当简单。还要注意,实现 和 ,因此我们可以在 和 的 和 属性中引用 bean
应用。XStreamMarshaller
Marshaller
Unmarshaller
xstreamMarshaller
marshaller
unmarshaller
此示例应用程序生成以下文件:settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings foo-enabled="false"/>
XML 配置命名空间
通过使用 OXM 命名空间中的标记,可以更简洁地配置编组程序。 要使这些标记可用,您必须首先在 XML 配置文件的前导码。以下示例演示如何执行此操作:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oxm="http://www.springframework.org/schema/oxm" (1)
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/oxm
https://www.springframework.org/schema/oxm/spring-oxm.xsd"> (2)
1 | 引用架构。oxm |
2 | 指定架构位置。oxm |
该架构使以下元素可用:
每个标签在其各自的编组器部分都有解释。举个例子, JAXB2 封送器的配置可能类似于以下内容:
<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>
JAXB公司
JAXB 绑定编译器将 W3C XML 模式转换为一个或多个 Java 类、一个文件,可能还有一些资源文件。JAXB 还提供了一种方法
从带注释的 Java 类生成模式。jaxb.properties
Spring 支持将 JAXB 2.0 API 作为 XML 编组策略,遵循 Marshaller
和 Unmarshaller
中描述的 and 接口。
相应的集成类驻留在包中。Marshaller
Unmarshaller
org.springframework.oxm.jaxb
用Jaxb2Marshaller
该类同时实现 Spring 和接口。它需要上下文路径才能运行。您可以通过设置属性来设置上下文路径。上下文路径是冒号分隔的 Java 包的列表
包含架构派生类的名称。它还提供物业,
它允许您设置要由编组器支持的类数组。图式
验证是通过向 Bean 指定一个或多个模式资源来执行的,如以下示例所示:Jaxb2Marshaller
Marshaller
Unmarshaller
contextPath
classesToBeBound
<beans>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.springframework.oxm.jaxb.Flight</value>
<value>org.springframework.oxm.jaxb.Flights</value>
</list>
</property>
<property name="schema" value="classpath:org/springframework/oxm/schema.xsd"/>
</bean>
...
</beans>
XML 配置命名空间
该元素配置一个 ,
如以下示例所示:jaxb2-marshaller
org.springframework.oxm.jaxb.Jaxb2Marshaller
<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>
或者,可以使用子元素提供要绑定到封送器的类列表:class-to-be-bound
<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Airport"/>
<oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Flight"/>
...
</oxm:jaxb2-marshaller>
下表描述了可用的属性:
属性 | 描述 | 必填 |
---|---|---|
|
编组员的 ID |
不 |
|
JAXB 上下文路径 |
不 |
抖动
JiBX 框架提供了类似于 Hibernate 为 ORM 提供的解决方案: 绑定定义定义了如何将 Java 对象转换为 Java 对象或从 Java 对象转换的规则 在准备绑定并编译类之后,一个 JiBX 绑定编译器 增强类文件并添加代码以处理类的转换实例 从 XML 或到 XML。
有关 JiBX 的更多信息,请参阅 JiBX Web
网站。Spring 集成类驻留在包中。org.springframework.oxm.jibx
用JibxMarshaller
该类实现 and 接口。要操作,它需要要封送的类的名称,您可以
使用属性进行设置。(可选)可以通过设置属性来设置绑定名称。在下面的示例中,我们绑定了该类:JibxMarshaller
Marshaller
Unmarshaller
targetClass
bindingName
Flights
<beans>
<bean id="jibxFlightsMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass">org.springframework.oxm.jibx.Flights</property>
</bean>
...
</beans>
为单个类配置了 A。如果要封送多个
类,则必须配置具有不同属性值的多个实例。JibxMarshaller
JibxMarshaller
targetClass
XStream
XStream 是一个简单的库,用于将对象序列化为 XML 并再次返回。它没有 需要任何映射并生成干净的 XML。
有关 XStream 的详细信息,请参阅 XStream
网站。Spring 集成类驻留在包中。org.springframework.oxm.xstream
用XStreamMarshaller
不需要任何配置,可以在
应用程序上下文。要进一步自定义 XML,您可以设置别名映射,
它由映射到类的字符串别名组成,如以下示例所示:XStreamMarshaller
<beans>
<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="aliases">
<props>
<prop key="Flight">org.springframework.oxm.xstream.Flight</prop>
</props>
</property>
</bean>
...
</beans>
默认情况下,XStream 允许取消编组任意类,这可能导致
不安全的 Java 序列化效果。因此,我们不建议使用 从外部源(即 Web)取消封送 XML 的 XML,因为这样可以
导致安全漏洞。 如果选择使用 从外部源取消封送 XML ,
设置 上的属性,如以下示例所示:
这样做可确保只有已注册的类才有资格取消编组。 此外,您可以注册自定义
转换器,以确保只有受支持的类才能取消编组。你可能会
想要添加 a 作为列表中的最后一个转换器,除了
显式支持应支持的域类的转换器。作为
结果,默认的 XStream 转换器具有较低的优先级和可能的安全性
漏洞不会被调用。 |
请注意,XStream 是 XML 序列化库,而不是数据绑定库。 因此,它的命名空间支持有限。因此,它相当不适合使用 在 Web 服务中。 |