web-dev-qa-db-fra.com

Comment renommer la clé racine dans la sérialisation JSON avec Jackson

J'utilise Jackson pour la sérialisation JSON d'une liste d'objets.

Voici ce que je reçois:

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

Mais je veux ceci:

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

Ci-dessous, mon approche à ce sujet:

Interface:

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

Classe d'implémentation:

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

Sérialisation 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);
    }
}

Tester:

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

Voici ce que je reçois:

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

Mais je veux ceci:

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

J'ai essayé toutes les solutions suggérées que j'ai pu trouver mais que je n'ai pas atteintes. J'ai regardé:

Ou est-ce que je manque quelque chose? J'utilise Jackson 1.9.12 pour cela. Toute aide à cet égard est la bienvenue.

24
user2266861

Par défaut, Jackson utilise l'une des deux annotations lorsque vous tentez de déterminer le nom de la racine à afficher pour les valeurs renvoyées - @XmlRootElement ou @JsonRootName . Il s'attend à ce que cette annotation se trouve sur le type en cours de sérialisation, sinon elle utilisera le nom simple du type comme nom racine.

Dans votre cas, vous sérialisez une liste, raison pour laquelle le nom racine est 'ArrayList' (nom simple du type en cours de sérialisation). Chaque élément de la liste peut être d'un type annoté avec @JsonRootName, mais la liste elle-même n'est pas

Lorsque la valeur racine que vous essayez d'encapsuler est une collection, vous avez besoin d'un moyen de définir le nom de l'encapsulation:

Classe de support/emballage

Vous pouvez créer une classe wrapper pour contenir la liste, avec une annotation définissant le nom de la propriété souhaitée (vous ne devez utiliser cette méthode que si vous n'avez pas le contrôle direct du processus de transformation 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);

Auteur d'objet

C'est l'option préférable. Utilisez une instance ObjectWriter configurée pour générer le JSON. En particulier, nous nous intéressons à la méthode 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);
29
Perception

Je sais, je suis en retard, mais j'ai une meilleure approche qui n'exige pas de classe de détenteur/d'emballage. Il sélectionne la clé racine de l'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;
    }
}

Voici la classe de test: -

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

    }


}

Il donnera la sortie suivante

{"Products":[{"name":null,"description":"Product 4 - Test"}]}
7
Vaibhav
@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;
    }
}
0
Jose Montestruque