当前位置: 首页 > 知识库问答 >
问题:

Spring Framework JSON序列化为数组而不是对象

田硕
2023-03-14

在我使用Spring的web应用程序中,我们希望使用一个定制的JSON结构。Spring默认采用这样的POJO:

public class Model {

    private int id;
    private String name;

    public Model(){}

    public Model(int id, String name){
        this.id = id;
        this.name = name;
    }
}

并把它变成这样:

{"id":1, "name":"Bob"}

对于我们的应用程序,我们希望将其变成这样:

[1, "Bob"]

我想使用Spring的默认序列化逻辑来检测Java类型(int,字符串,集合等)并映射到适当的JSON类型,但只需将包装对象更改为数组而不是带有字段的对象。

这是我到目前为止拥有的序列化程序(它将在模型中实现@JsonSerialize(使用=序列化器.class)),但不希望重写Spring已经实现的所有逻辑。

public class Serializer extends JsonSerializer<Model> {
    @Override
    public void serialize(Model value, JsonGenerator jgen, SerializerProvider provider)
        throws IOException, JsonProcessingException {

        jgen.writeStartArray();
        jgen.writeString(value.id);
        .... other values ...
        jgen.writeEndArray();

    }
}

如何连接到预先存在的序列化程序,以便这个新的序列化程序将像默认的一样与任何POJO一起工作(不仅仅是模型类,而是我们需要序列化为数组的任何类似或子类)?这可能有混合属性,并且没有特定的属性命名约定。

我想避免为每个不同的模型类编写自定义序列化程序(...其他值 ...)部分。

共有2个答案

郎和志
2023-03-14

您可以为此使用@JsonValue注释。示例:

public class Model {

  private int id;

  public Model(){}

  public Model(int id){
    this.id = id;
  }

  @JsonValue
  public int[] getValue() {
    return new int[]{this.id};
  } 
}
宰父夕
2023-03-14

看一下Apache BeanUtils库,尤其要注意BeanUtils.populate()方法

该方法的作用是将任何给定的< code >对象转换为< code >映射

Model model = ...; // get your model from some place

Map<String, Object> properties = new HashMap<>();

BeanUtils.populate(model, properties);

// Exception handling and special cases left as an excercise

上面递归地填充了< code>properties映射,这意味着如果您的< code>Model有一个名为< code>otherModel的属性,其类型为< code>OtherModel,那么< code>properties映射将在匹配< code>otherModel键的条目处有另一个映射,对于其他嵌套的POJOs也是如此。

一旦你有了属性映射,你想要序列化为数组元素的内容将在它的值中。所以,像这样的东西应该能起到作用:

public List<Object> toArray(Map<String, Object> properties) {
    List<Object> result = new ArrayList<>();

    for (Object obj : properties.values()) {
        Object elem = null;
        if (obj != null) {
            Class<?> clz = obj.getClass();
            if (Map.class.isAssignableFrom(clz)) {
                elem = toArray((Map<String, Object>) obj); // recursion!
            } else {
                elem = obj;
            }
        }
        result.add(elem); // this adds null values
                          // move 1 line up if you don't
                          // want to serialize nulls
    }
    return result;
}

然后,在调用toArray()方法后,您将拥有一个List

List<Object> array = toArray(properties);
return array; // return this array, i.e. from a Controller 

免责声明:

请将此作为指南,而非最终解决方案。我尽量小心,但代码可能会有错误。我很确定它需要对POJOs的数组和< code>Iterable进行特殊处理。毫无疑问,它缺乏异常处理。它只适用于POJOs。如果提供的对象有循环引用,它可能会爆炸。没测试过!

 类似资料:
  • 我有以下JSON文件要反序列化

  • 情况:我希望使用ObjectOutputStream将一组对象(不同类型)从客户端发送到服务器。 问题:对象数组不可序列化(我得到一个not serializable异常)。 我尝试了什么:我创建了一个扩展Object并实现Serializable的虚拟类。但是我不能将原始对象数组强制转换为此类。 是否有任何方法可以序列化对象数组?

  • 我有一个回应 正文 下面是我要映射的coreV2Response类

  • 问题内容: 我有由第三方编码为固定长度数组的json’ed 元组数组: 我想使用json魔术来获取的实例列表 请帮助我放置适当的注释,以使ObjectMapper发挥作用。 我无法控制传入的格式,而我所有的google’n都以答案来回答如何将适当的json对象(而非数组)数组映射到对象列表 问题答案: 添加以下注释: 并且它应该根据需要序列化条目。 另外:然后使用它来强制执行特定顺序是最安全的,因

  • 问题内容: 我正在将CakePHP数组的返回值转换为JSON,目前它是这样的: 我希望它像这样: 我正在尝试 设置:: extract(’{n} .Model’,$ data) Hash :: extract(’{n} .Model’,$ data)根本没有运气。 完整代码: 问题答案: 为选项设置,而不是。An 表示可能需要序列化多个视图变量,这要求将它们打包到单独的对象属性中。 那应该给您期望

  • 通常,当您要将对象序列化为JSON字符串时,会执行以下操作: 我想知道是否可以将对象直接序列化为而不是字符串?即类似这样的东西(伪代码): 我知道我可以先将对象序列化为String,然后将其反序列化为