java - Jackson YAML - 将 null 序列化为空值

标签 java serialization null jackson yaml

我正在尝试自定义字符串的序列化以避免 YAML 文件中的 null 值。

我到目前为止的代码:

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 正在写入一个空字符串,而我试图完全拥有一个空值。

期望的结果:

---
aNullObject: 
aString: "test"
anEmptyString: ""

我尝试使用 jgen.writeRaw(""); 但出现此错误:

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 写入空的原始值。而且您还必须提供一个自定义空序列化程序来写入此原始值。

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))
}}

关于java - Jackson YAML - 将 null 序列化为空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53163648/

相关文章:

java - 如何使用JavaScript函数重定向到Struts2中的另一个jsp页面

java - 如何正确从文件加载 JFrame?

java - jackson 序列号 : Unwrap collection elements using

c++ - 异常 "Texture cannot be null"直接 X

java - 自定义异常(例如 IllegalArgumentException)以获得良好的日志信息

java - Business Objects 4.1 OpenDocument 使用企业登录进行编辑

java - 如何从另一个范围中过滤掉一个范围内的数字

c# - 字符串序列化和反序列化问题

C# 可空相等操作,为什么 null <= null 解析为 false?

java - Spring 中未选择文件提交表单失败