Spring 3.0 的一个新特性是 O/X Mapper
,下面简称 OXM
,O 代表 Object,X 代表 XML,它的目的是实现 Java POJO 对象和 XML 文档之间的互相转换。
Spring O/X Mapper 定义统一的接口,实现由第三方框架提供。要使用 Spring 的 O/X 功能,您需要一个在 Java 对象和 XML 之间来回转换的库,Castor 就是这样一个流行的第三方工具,本文将使用这个工具,其他这样的工具包括 XMLBeans、Java Architecture for XML Binding (JAXB)、JiBX 和 XStream。
项目目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ├── main │ ├── java │ │ └── com │ │ └── xtuer │ │ └── bean │ │ └── User.java │ └── resources │ ├── castor.properties │ ├── oxm-user.xml │ └── spring-beans.xml └── test ├── java │ └── TestOxm.java └── resources
User 是一个普通的 Java 类,即 POJO
spring-beans.xml 为 Spring 的配置文件
oxm-user.xml 用来描述类的属性映射到 xml 时的 tag name,OXM 的好处是对象的属性名和 xml 里面对应的 tag name 可以不一样,这样在不同的系统间交互数据时很有用
TestOxm 为测试类
castor.properties: 默认生成的 xml 是没有缩进的,不利于阅读,为了生成格式化的 xml,需要在配置文件 castor.properties 中定义 org.exolab.castor.indent = true
,Castor 会读取这个文件
术语:
Marshalling: 把 POJO 映射为 xml
Unmarshalling: 把 xml 映射为 POJO
Gradle 依赖 1 2 3 4 5 6 7 8 9 10 11 compile 'org.springframework:spring-webmvc:4.3.0.RELEASE' compile 'org.springframework:spring-oxm:4.3.0.RELEASE' compile 'org.codehaus.castor:castor-xml:1.4.1' compile 'commons-io:commons-io:2.4' compile 'org.projectlombok:lombok:1.16.10' compile 'com.alibaba:fastjson:1.2.17' testCompile 'org.springframework:spring-test:4.3.0.RELEASE' testCompile 'junit:junit:4.12'
User.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.xtuer.bean;import lombok.Getter;import lombok.Setter;@Getter @Setter public class User { private int id; private String username; private String password; public User () { } public User (int id, String username, String password) { this .id = id; this .username = username; this .password = password; } }
oxm-user.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <mapping > <class name ="com.xtuer.bean.User" > <map-to xml ="user" /> <field name ="id" type ="integer" > <bind-xml name ="user_id" node ="element" /> </field > <field name ="username" type ="string" > <bind-xml name ="username" node ="element" /> </field > <field name ="password" type ="string" > <bind-xml name ="password" node ="element" /> </field > </class > </mapping >
map-to
的 xml
的属性值是生成的 xml 的根节点的标签名field
的 name
的属性值是 POJO 的属性名bind-xml
的 name
的属性值是生成的 xml 中属性对于的标签名
spring-beans.xml 1 2 3 4 5 6 7 8 9 10 11 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation =" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id ="marshaller" class ="org.springframework.oxm.castor.CastorMarshaller" > <property name ="mappingLocation" value ="classpath:oxm-user.xml" /> </bean > </beans >
CastorMarshaller 同时实现了 Marshaller 和 Unmarshaller 接口
castor.properties 1 org.exolab.castor.indent = true
测试: TestOxm.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import com.alibaba.fastjson.JSON;import com.xtuer.bean.User;import org.apache.commons.io.FileUtils;import org.apache.commons.io.IOUtils;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.oxm.castor.CastorMarshaller;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringRunner;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;@RunWith(SpringRunner.class) @ContextConfiguration({"classpath:spring-beans.xml"}) public class TestOxm { @Autowired private CastorMarshaller marshaller; private static final String FILE_NAME = "/Users/Biao/Desktop/user.xml" ; @Test public void testMarshalling () throws Exception { User user = new User(12 , "Alice" , "Passw0rd" ); FileOutputStream fos = FileUtils.openOutputStream(new File(FILE_NAME)); marshaller.marshal(user, new StreamResult(fos)); IOUtils.closeQuietly(fos); } @Test public void testUnmarshalling () throws Exception { FileInputStream fis = FileUtils.openInputStream(new File(FILE_NAME)); User user = (User)marshaller.unmarshal(new StreamSource(fis)); System.out.println(JSON.toJSONString(user)); IOUtils.closeQuietly(fis); } }
运行 testMarshalling()
生成文件 /Users/Biao/Desktop/user.xml
,内容如下
1 2 3 4 5 6 <?xml version="1.0" encoding="UTF-8"?> <user > <user_id > 12</user_id > <username > Alice</username > <password > Passw0rd</password > </user >
运行 testUnmarshalling()
输出
1 {"id":12,"password":"Passw0rd","username":"Alice"}
问题 上面例子中 User 的属性都是简单属性,没有数组,List,Map,Set,复杂对象等,在网络上找到的资料基本都是用的简单属性,实际开发中肯定是不够用的,还需要进一步研究相关内容。