Is there an annotation for Jackson to suppress unnecessary JSON wrapping?
The class I'm serializing:
public class LogsDTO {
/** The logs. */
private List<LogDTO> logs;
/** Meta data. */
private Meta meta = new Meta();
// more
}
And the generated JSON:
{"LogsDTO":{"logs":[{"id":11,"archived":false}],"meta":{"totalPages":0}}}
I would like my JSON to look like this:
{"logs":[{"id":11,"archived":false}],"meta":{"totalPages":0}}
Is there some annotation way to make this happen?
thank
source to share
@JsonRootName
: An annotation for the class used to specify the name of the "wrapper" entry to use for the root value if root support is enabled.
Says in jackson files: https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
The linked Jira task: http://jira.codehaus.org/browse/JACKSON-630 version 1.9 and above support it.
While examining the @JsonRootName source code ,
They commented out the alwaysWrap method.
/ * * An optional marker property that can be specified
true
to force * the boxing of the root element, whether globally * Root boxing is enabled or not. ** Note that the value is
false
generally understood to mean "use default values", * and will not block use of the shell if use is specified by global functions. * * @ considering 2.4 public boolean alwaysWrap () default false; * /
They have a plan to activate it at v2.5
As of 2.4, one missing feature is the "alwaysWrap" property, which will hopefully be added in 2.5 and will be used to force root name wrapping * for particular types.
source to share
Use card type Map<String, Object>
. This not a good solution doesn't use annotations. I just want to show another possibility, how to avoid json wrapping:
public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
List<LogDTO> logs = new ArrayList<LogDTO>();
logs.add(new LogDTO(1, true));
logs.add(new LogDTO(2, false));
logs.add(new LogDTO(3, true));
map.put("logs", logs);
map.put("meta", new Meta(33));
Gson gson = new GsonBuilder().create();
String json = gson.toJson(map);
LogsDTO dto = gson.fromJson(json, LogsDTO.class);
System.out.println(json);
System.out.println(dto);
}
gives:
{
"meta":{
"id":33
},
"logs":[
{
"id":1,
"archived":true
},
{
"id":2,
"archived":false
},
{
"id":3,
"archived":true
}
]
}
and
LogsDTO [logs=[Log [id=1, archived=true], Log [id=2, archived=false], Log [id=3, archived=true]], meta=Meta [id=33]]
source to share
I decided to use it with a custom serializer by disabling global wrapping and enabling wrapping for each class. It seems that even when you complete the global boxing, Jackson is adding a wrapper for the list items of the class that has boxing. One difference from your code is that for me the list was wrapped in its own class. It was something like this:
@JsonTypeName("interface")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) // wrapping per class instead of global in the mapper
public class InterfaceDTO
{
private InterfaceIpListDTO interfaceIpListDTO; // The list property for which I want to turn off wrapping
@JsonSerialize(using = com.tufin.securetrack.integration.rest.facade.serializer.InterfaceIPListWithoutWrapperNameSerializer.class) // Gonen
public InterfaceIpListDTO getInterfaceIpListDTO() {
return interfaceIpListDTO;
}
}
public class InterfaceIPListWithoutWrapperNameSerializer extends JsonSerializer<InterfaceIpListDTO>{
@Override
public void serialize(InterfaceIpListDTO interfaceIpListDTO, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartArray();
for (InterfaceIpDTO interfaceIpDTO : interfaceIpListDTO.getInterfaceIpDTOs()) {
jsonGenerator.writeObject(interfaceIpDTO);
}
jsonGenerator.writeEndArray();
}
}
source to share