问题描述
我正在尝试自定义字符串的序列化,以避免YAML
文件中的null
值.
I am trying to customise the serialisation of strings to avoid null
values in the YAML
file.
我到目前为止的代码:
YAMLFactory yamlFactory = new YAMLFactory();
ObjectMapper mapper = new ObjectMapper(yamlFactory);
DefaultSerializerProvider sp = new DefaultSerializerProvider.Impl();
sp.setNullValueSerializer(new NullSerializer());
ObjectMapper m = new ObjectMapper();
mapper.setSerializerProvider(sp);
Map<String, Object> data = new HashMap<>();
data.put("aString", "test");
data.put("aNullObject", null);
data.put("anEmptyString", "");
String output = mapper.writeValueAsString(data);
System.out.println(output);
NullSerializer
:
public class NullSerializer extends JsonSerializer<Object> {
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeString("");
}
}
结果:
---
aNullObject: ""
aString: "test"
anEmptyString: ""
问题是writeString
正在写一个空字符串,而我正在尝试完全使用一个空值.
The problem is that writeString
is writing an empty string, and I'm trying to have an empty value entirely.
所需结果:
---
aNullObject:
aString: "test"
anEmptyString: ""
我尝试使用jgen.writeRaw("");
,但出现此错误:
I tried to use jgen.writeRaw("");
but I get this error:
Caused by: java.lang.UnsupportedOperationException: Operation not supported by generator of type com.fasterxml.jackson.dataformat.yaml.YAMLGenerator
at com.fasterxml.jackson.core.JsonGenerator._reportUnsupportedOperation(JsonGenerator.java:1967)
at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.writeRaw(YAMLGenerator.java:590)
at com.example.jackson.NullSerializer.serialize(NullSerializer.java:13)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeNull(SerializerProvider.java:1127)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:711)
... 7 more
推荐答案
对我来说,禁用"MINIMIZE_QUOTES"功能不起作用,仍然会写入一个空字符串.我发现的唯一解决方案是重写ObjectMapper和YamlGenerator并允许YamlGenerator写入空的原始值.而且,您还必须提供一个自定义的null序列化程序,该序列化程序可以写入此原始值.
For me disabling of "MINIMIZE_QUOTES" feature didn't work, still, an empty string is written. The only solution I found was to override ObjectMapper and YamlGenerator and to allow YamlGenerator to write empty raw value. And also you have to provide a custom null serializer that writes this raw value.
class YamlObjectMapper(yamlFactory: YAMLFactory) : ObjectMapper(yamlFactory) {
init {
val dS = DefaultSerializerProvider.Impl()
dS.setNullValueSerializer(NullSerializer)
setSerializerProvider(dS)
}}
class RawYAMLFactory : YAMLFactory() {
override fun _createGenerator(out: Writer?, ctxt: IOContext?): YAMLGenerator? {
val feats = _yamlGeneratorFeatures
return RawYamlGenerator(ctxt, _generatorFeatures, feats, _objectCodec, out, _version)
}}
private object NullSerializer : JsonSerializer<Any?>() {
override fun serialize(value: Any?, jgen: JsonGenerator, provider: SerializerProvider?) {
jgen.writeRaw("")
}}
private class RawYamlGenerator(ctxt: IOContext?, jsonFeatures: Int, yamlFeatures: Int,
codec: ObjectCodec, out: Writer?, version: DumperOptions.Version?)
: YAMLGenerator(ctxt, jsonFeatures, yamlFeatures, codec, out, version) {
override fun writeRaw(c: String) {
_writeContext.writeValue()
_emit(_scalarEvent("", DumperOptions.ScalarStyle.PLAIN))
}}
这篇关于Jackson YAML-将null序列化为空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!