【问题标题】:Serialize JSON field as JSON将 JSON 字段序列化为 JSON
【发布时间】:2013-12-11 18:36:30
【问题描述】:

如果字符串字段包含 JSON 对象,我正在尝试将其序列化为 JSON。为此,我编写了一个自定义序列化程序:

public class TryJsonStringSerializer extends JsonSerializer<String> {
    @Override
    public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) 
            throws IOException, JsonProcessingException {
        if (value == null) {
            return;
        }
        value = value.trim();
        if (value.startsWith("{") && value.endsWith("}")) {
            jsonGenerator.writeRaw(value);
        } else {
            jsonGenerator.writeString(value);
        }
    }

}

但我收到以下错误:

org.codehaus.jackson.JsonGenerationException: Can not write a field name, expecting a value
org.codehaus.jackson.impl.JsonGeneratorBase._reportError(JsonGeneratorBase.java:480)
org.codehaus.jackson.impl.Utf8Generator.writeFieldName(Utf8Generator.java:292)
org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:422)
org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:122)
org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:71)
org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86)
org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1613)
...

实现这一目标的最佳方法是什么?

【问题讨论】:

  • 上面的异常跟踪没有显示你的方法。你确定这是失败的原因吗?
  • 如果我输入 jsonGenerator.writeString(value); 而不是 jsonGenerator.writeRaw(value); 一切正常。

标签: java json serialization jackson


【解决方案1】:
public class TryJsonStringSerializer extends JsonSerializer<String> {

    private RawSerializer<String> rawSerializer = new RawSerializer<String>(String.class);
    private ToStringSerializer stringSerializer = ToStringSerializer.instance;

    @Override
    public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) 
            throws IOException, JsonProcessingException {
        if (value == null) {
            return;
        }
        value = value.trim();
        if (value.startsWith("{") && value.endsWith("}")) {
            rawSerializer.serialize(value, jsonGenerator, serializerProvider);
        } else {
            stringSerializer.serialize(value, jsonGenerator, serializerProvider);
        }
    }

}

【讨论】:

    【解决方案2】:

    你可能想使用特殊的注解:@JsonRawValue,见docs

    【讨论】:

    • 如果它不是有效的 JSON,我仍想将其视为字符串。我该怎么做?
    • 也许有一些方法可以做到这一点,但我最好将此逻辑移到序列化和相关内容之外。如果您不确定是否存在有效的 JSON,那么它就是字面意义上的字符串。您检查前导 { 或尾随 } 并不意味着内容是有效的 JSON。
    • 检查 {} 是不够的,但我可以尝试解析它,如果通过,应该就足够了。如果没有,那么我可以把它写成一个字符串。我试图使示例中的逻辑尽可能简单。
    • 我建议通过添加 JSON 和 String 类型的额外字段来子类化某些基类,或者(我的首选方式)创建一些具有通用属性的聚合类。然后会更容易理解您在使用什么 - JSON 对象或纯字符串。拥有一些“魔法”对象,它们针对不同的内容以不同的方式表现从来都不是一个好主意。恕我直言。
    • 我找到了一种方法,但你的观察非常好。 +1。
    猜你喜欢
    • 2018-03-31
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 2019-03-28
    相关资源
    最近更新 更多