Jackson序列化Xml声明

公共实体类

@JacksonXmlRootElement(localName = "stu")
public class Stu {
	private String name;
	
	private String age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}
	
}

最简单的序列化

public static void main(String[] args) throws JsonProcessingException {
	XmlMapper xmlMapper = new XmlMapper();
	Stu stu = new Stu();
	stu.setName("学生");
	stu.setAge("18");
	String xml = xmlMapper.writeValueAsString(stu);
	System.out.println(xml);
}

结果为

<stu><name>学生</name><age>18</age></stu>

没有xml声明?
接着往下看

添加Xml声明

public static void main(String[] args) throws JsonProcessingException {
	XmlMapper xmlMapper = new XmlMapper();
	//只需要这一步,设置WRITE_XML_DECLARATION为true
	xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
	Stu stu = new Stu();
	stu.setName("学生");
	stu.setAge("18");
	String xml = xmlMapper.writeValueAsString(stu);
	System.out.println(xml);
}

结果为

<?xml version='1.0' encoding='UTF-8'?><stu><name>学生</name><age>18</age></stu>

纳尼?<?xml version='1.0' encoding='UTF-8'?>怎么是单引号?

Jackson生成xml声明源码

先看看Jackson源码,怎么生成的xml声明

看com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator
在这里插入图片描述
继续跟踪到com.ctc.wstx.sw.BufferingXmlWriter类
在这里插入图片描述
mUseDoubleQuotesInXmlDecl 字段为true时才使用双引号
mUseDoubleQuotesInXmlDecl 字段在BufferingXmlWriter的父类 com.ctc.wstx.sw.XmlWriter 中
在这里插入图片描述
竟然用 final 修饰?
看来只能在实例化BufferingXmlWriter对象时设置值了
在这里插入图片描述
在这里插入图片描述
与WriterConfig有关,继续向上跟踪源码到 com.ctc.wstx.stax.WstxOutputFactory 类
在这里插入图片描述
在这里插入图片描述
mConfig是在 WstxOutputFactory 类的构造器设置的,还是protected修饰
我可以写个子类,用默认构造器先调用父类构造器,再给mConfig设置值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
PROP_USE_DOUBLE_QUOTES_IN_XML_DECL 的值是10,可是不是public修饰的,不过没关系。
在这里插入图片描述
convertToBoolean 的第一个参数竟然没用到,一会儿我们可以这么调用方法

mConfig.setProperty(null, 10, true);

具体实现后面再说。
但是,怎么让XmlMapper使用我写的类呢?看类名是个序列化工厂
先来看看WstxOutputFactory 类的继承关系
在这里插入图片描述
我们再看看XmlMapper类的构造器
在这里插入图片描述
发现了吗?可以传入 XMLOutputFactory 对象,也就是说可以传入 WstxOutputFactory 对象
再看 XmlFactory 的构造器
在这里插入图片描述
当 XMLInputFactory 参数为 null 时,则使用默认的 XMLInputFactory 对象,当 XMLOutputFactory 参数为 null 时,则使用默认的 XMLOutputFactory 对象。
所以我们可以使用
在这里插入图片描述
创建XmlMapper对象

在XML声明中使用双引号 方案一

创建 WstxOutputFactory 的子类

import com.ctc.wstx.stax.WstxOutputFactory;

public class DoubleQuotesOutputFactory extends WstxOutputFactory {

	public DoubleQuotesOutputFactory() {
		super();
		mConfig.setProperty(null, 10, true);
	}

}

创建XmlMapper对象

XmlMapper xmlMapper = new XmlMapper(null, new DoubleQuotesOutputFactory());

完整代码

public static void main(String[] args) throws JsonProcessingException {
	XmlMapper xmlMapper = new XmlMapper(null, new DoubleQuotesOutputFactory());
	//只需要这一步,设置WRITE_XML_DECLARATION为true
	xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
	Stu stu = new Stu();
	stu.setName("学生");
	stu.setAge("18");
	String xml = xmlMapper.writeValueAsString(stu);
	System.out.println(xml);
}

结果为

<?xml version="1.0" encoding="UTF-8"?><stu><name>学生</name><age>18</age></stu>

优化 WstxOutputFactory 的子类

在 WstxOutputFactory 类中有个方法
在这里插入图片描述
向下跟踪源码
在这里插入图片描述
关键的一步是 findPropertyId(propName)
继续跟踪进 WriterConfig 类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
P_USE_DOUBLE_QUOTES_IN_XML_DECL 是 public 修饰的
PROP_USE_DOUBLE_QUOTES_IN_XML_DECL 的值就是10

所以 WstxOutputFactory 的子类可以优化为下面的代码

import com.ctc.wstx.api.WstxOutputProperties;
import com.ctc.wstx.stax.WstxOutputFactory;

public class DoubleQuotesOutputFactory extends WstxOutputFactory {

	public DoubleQuotesOutputFactory() {
		super();
		this.setProperty(WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
	}

}

运行结果仍然为

<?xml version="1.0" encoding="UTF-8"?><stu><name>学生</name><age>18</age></stu>

在XML声明中使用双引号 方案二

不多说了,上代码

public static void main(String[] args) throws JsonProcessingException {
	XmlMapper xmlMapper = new XmlMapper();
	XmlFactory factory = xmlMapper.getFactory();
	XMLOutputFactory xmlOutputFactory = factory.getXMLOutputFactory();
	xmlOutputFactory.setProperty(WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
	//只需要这一步,设置WRITE_XML_DECLARATION为true
	xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
	Stu stu = new Stu();
	stu.setName("学生");
	stu.setAge("18");
	String xml = xmlMapper.writeValueAsString(stu);
	System.out.println(xml);
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值