将JSON字段序列化为JSON。

3

如果一个字符串中包含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)
...

什么是达成此目标的最佳方式?

以上的异常跟踪并没有显示出你的方法。你确定是这个方法出了问题吗? - Hot Licks
如果我使用 jsonGenerator.writeString(value); 而不是 jsonGenerator.writeRaw(value); ,一切都能工作。 - Adrian Ber
2个回答

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

}

1

您可能需要使用特殊注释:@JsonRawValue,请参见文档


如果它不是有效的 JSON,我仍然想将其视为字符串。我该怎么做? - Adrian Ber
也许有某种方法可以做到这一点,但最好将此逻辑移出序列化和相关内容。如果您不确定是否存在有效的 JSON,请使用字符串字面量。检查前导 { 或尾随 } 并不意味着内容是有效的 JSON。 - jdevelop
仅检查{}是不够的,但我可以尝试解析它,如果成功,则应该足够。如果不行,那么我可以将其写成字符串。我试图尽可能简单地维护示例中的逻辑。 - Adrian Ber
我建议要么通过添加额外的JSON和String类型字段来子类化一些基类,要么(我更喜欢的方式)创建一些带有通用属性的聚合类。然后,就更容易理解你正在处理的是JSON对象还是纯字符串。拥有一些“神奇”的对象,它们对不同的内容表现出不同的行为,从来都不是一个好主意。在我看来。 - jdevelop
我找到了一种方法,但是你的观察非常好。+1。 - Adrian Ber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接