java - not - jsonproperty
Cómo cambiar el nombre de la clave raíz en la serialización JSON con Jackson (4)
Bueno, de manera predeterminada, Jackson utiliza una de las dos anotaciones cuando intenta determinar el nombre de la raíz que se mostrará para los valores ajustados: @XmlRootElement
o @JsonRootName
. Espera que esta anotación esté en el tipo que se está serializando, de lo contrario, utilizará el nombre simple del tipo como el nombre raíz.
En su caso, está serializando una lista, por lo que el nombre raíz es ''ArrayList'' (nombre simple del tipo que se serializa). Cada elemento de la lista puede ser de un tipo anotado con @JsonRootName, pero la lista en sí no lo es .
Cuando el valor raíz que intenta envolver es una colección, necesita alguna forma de definir el nombre de ajuste:
Clase de contenedor / envoltura
Puede crear una clase de envoltorio para contener la lista, con una anotación para definir el nombre de la propiedad deseada ( solo necesita usar este método cuando no tiene control directo del proceso de transformación 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);
Escritor de objetos
Esta es la opción preferible. Utilice una instancia de ObjectWriter
configurada para generar el JSON. En particular, estamos interesados en el método 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);
Estoy utilizando Jackson para la serialización JSON de una lista de objetos.
Esto es lo que obtengo:
{"ArrayList":[{"id":1,"name":"test name"}]}
Pero quiero esto:
{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root name.
A continuación es mi enfoque a esto:
Interfaz:
public interface MyInterface {
public long getId();
public String getName();
}
Clase de implementación:
@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
}
Serialización 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);
}
}
Prueba:
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);
Esto es lo que obtengo:
{"ArrayList":[{"id":1,"name":"test name"}]}
Pero quiero esto:
{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root name.
He intentado todas las soluciones sugeridas que pude encontrar pero no logré mi objetivo. He mirado a
- Jackson: serialización de colección personalizada a JSON
- ¿Cómo cambio el nombre de la clave raíz de un JSON con Java Jackson?
- Jackson: serialización de colección personalizada a JSON
¿O me estoy perdiendo algo? Estoy usando jackson 1.9.12 para esto. Cualquier ayuda en este sentido es bienvenida.
Lo sé, llego tarde, pero tengo un mejor enfoque que no requiere Holder / Wrapper Class. Se elige la clave de la raíz de la anotación.
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;
}
}
Aquí está la clase de prueba: -
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));
}
}
Dará salida siguiente
{"Products":[{"name":null,"description":"Product 4 - Test"}]}
Necesitas usar esta anotación en la parte superior de la clase.
@JsonTypeName("rootname")
@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;
}
}