简体   繁体   English

如何使用Jackson在JSON序列化中重命名根密钥

[英]How to rename root key in JSON serialization with Jackson

I am using Jackson for JSON serialization of a list of objects. 我正在使用Jackson进行JSON序列化对象列表。

Here is what I get: 这是我得到的:

{"ArrayList":[{"id":1,"name":"test name"}]}

But I want this : 但我想要这个:

{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root name.

Below is my approach to this: 以下是我对此的处理方法:

Interface: 接口:

public interface MyInterface {
    public long getId();
    public String getName();
}

Implementation class: 实施班:

@JsonRootName(value = "rootname")
public class MyImpl implements MyInterface {
    private final long id;
    private String name;

    public MyImpl(final long id,final name) {
        this.id = id;
        this.name = name;
    }

   // getters     
}

JSon serialization: JSon序列化:

public class MySerializer {
    public static String serializeList(final List<MyInterface> lists) {
        //check for null value.Throw Exception
        final ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
        return mapper.writeValueAsString(lists);
    }
}

Test: 测试:

final List<MyInterface> list = new ArrayList<MyImpl>();
MyImpl item = new MyImpl(1L,"test name");
list.add(item);
final String json = MySerializer.serializeList(list);
System.out.println(json);

Here is what I get: 这是我得到的:

{"ArrayList":[{"id":1,"name":"test name"}]}

But I want this : 但我想要这个:

{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root     name.

I have tried all suggested solutions I could find but failed to achieve my goal. 我已经尝试了所有我能找到的建议解决方案,但未能实现我的目标。 I have looked at: 我看过:

Or am I missing something? 或者我错过了什么? I am using jackson 1.9.12 for this. 我正在使用杰克逊1.9.12。 Any help in this regard is welcome. 欢迎提供这方面的任何帮助。

Well, by default Jackson uses one of two annotations when trying to determine the root name to be displayed for wrapped values - @XmlRootElement or @JsonRootName . 好吧,默认情况下,Jackson在尝试确定要为包装值显示的根名称时使用两个注释之一 - @XmlRootElement@JsonRootName It expects this annotation to be on the type being serialized, else it will use the simple name of the type as the root name. 它希望这个注释在被序列化的类型上,否则它将使用该类型的简单名称作为根名称。

In your case, you are serializing a list, which is why the root name is 'ArrayList' (simple name of the type being serialized). 在您的情况下,您正在序列化列表,这就是根名称为“ArrayList”(要序列化的类型的简单名称)的原因。 Each element in the list may be of a type annotated with @JsonRootName, but the list itself is not . 列表中的每个元素可以是使用@JsonRootName注释的类型,但列表本身不是

When the root value you are trying to wrap is a collection then you need some way of defining the wrap name: 当您尝试换行的根值是一个集合时,您需要一些方法来定义换行名称:

Holder/Wrapper Class 持有人/包装类

You can create a wrapper class to hold the list, with an annotation to define the desired property name ( you only need to use this method when you do not have direct control of the ObjectMapper /JSON transformation process ): 您可以创建一个包装类来保存列表,并使用注释来定义所需的属性名称( 当您没有直接控制ObjectMapper / JSON转换过程时,您只需要使用此方法 ):

class MyInterfaceList {
    @JsonProperty("rootname")
    private List<MyInterface> list;

    public List<MyInterface> getList() {
        return list;
    }

    public void setList(List<MyInterface> list) {
        this.list = list;
    }
}

final List<MyInterface> lists = new ArrayList<MyInterface>(4);
lists.add(new MyImpl(1L, "test name"));
MyInterfaceList listHolder = new MyInterfaceList();
listHolder.setList(lists);
final String json = mapper.writeValueAsString(listHolder);

Object Writer 对象编写者

This is the preferable option. 这是更好的选择。 Use a configured ObjectWriter instance to generate the JSON. 使用已配置的ObjectWriter实例生成JSON。 In particular, we are interested in the withRootName method: 特别是,我们对withRootName方法感兴趣:

final List<MyInterface> lists = new ArrayList<MyInterface>(4);
lists.add(new MyImpl(1L, "test name"));
final ObjectWriter writer = mapper.writer().withRootName("rootName");
final String json = writer.writeValueAsString(lists);

I know, I am late , but I have better approach which don't require Holder/Wrapper Class. 我知道,我迟到了,但我有更好的方法,不需要Holder / Wrapper Class。 It picks root key from annotation. 它从注释中选择根密钥。

package com.test;

import com.fasterxml.jackson.annotation.JsonRootName;


@JsonRootName("Products")
public class ProductDTO {
    private String name;
    private String description;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Here is test class:- 这是测试类: -

package com.test;

import java.io.IOException;
import java.util.ArrayList;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;


public class ProductDTOTestCase {
    @Test
    public void testPersistAndFindById() throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        ProductDTO productDTO = new ProductDTO();
        productDTO.setDescription("Product 4 - Test");

        ArrayList<ProductDTO> arrayList = new ArrayList<ProductDTO>();
        arrayList.add(productDTO);

        String rootName = ProductDTO.class.getAnnotation(JsonRootName.class).value();
        System.out.println(mapper.writer().withRootName(rootName).writeValueAsString(arrayList));

    }


}

It will give following output 它将给出以下输出

{"Products":[{"name":null,"description":"Product 4 - Test"}]}
@JsonTypeName("usuarios")
@JsonTypeInfo(include= JsonTypeInfo.As.WRAPPER_OBJECT,use= JsonTypeInfo.Id.NAME)
public class UsuarioDT extends ArrayList<Usuario> {

    @JsonProperty("rowsAffected")
    private Integer afectados;

    public Integer getAfectados() {
        return afectados;
    }

    public void setAfectados(Integer afectados) {
        this.afectados = afectados;
    }
}

您需要在类的顶部使用此批注

@JsonTypeName("rootname")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM