是否有 jackson 注释来抑制不必要的 JSON 换行?
Is there a jackson annotation to suppress unnecessary wrapping of JSON?
我正在连载的class:
public class LogsDTO {
/** The logs. */
private List<LogDTO> logs;
/** Meta data. */
private Meta meta = new Meta();
// more
}
和生成的JSON:
{"LogsDTO":{"logs":[{"id":11,"archived":false}],"meta":{"totalPages":0}}}
我希望我的 JSON 看起来像:
{"logs":[{"id":11,"archived":false}],"meta":{"totalPages":0}}
有没有办法进行注释以便发生这种情况?
谢谢
@JsonRootName
:class 注释用于指示用于根值的 "wrapper" 条目的名称,如果启用了根包装。
杰克逊文档中说:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
相关Jira任务:http://jira.codehaus.org/browse/JACKSON-6301.9及以上版本支持
当调查 source code of @JsonRootName,
他们评论了 alwaysWrap 方法。
/*
* Optional marker property that can be defined as true
to force
* wrapping of root element, regardless of whether globally
* "root wrapping" is enabled or not.
*
* Note that value of false
is taken to mean "use defaults",
* and will not block use of wrapper if use is indicated by global features.
*
* @since 2.4
public boolean alwaysWrap() default false;
*/
他们计划在 v2.5 上激活它
As of 2.4, one missing feature is property "alwaysWrap", which is hoped * to be added in 2.5, and would be used to force root name wrapping * for individual types.
使用 Map<String, Object>
类型的地图。这个不是很好的解决方案不使用注释。我只想展示其他可能性如何避免 json 包装:
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);
}
产生:
{
"meta":{
"id":33
},
"logs":[
{
"id":1,
"archived":true
},
{
"id":2,
"archived":false
},
{
"id":3,
"archived":true
}
]
}
和
LogsDTO [logs=[Log [id=1, archived=true], Log [id=2, archived=false], Log [id=3, archived=true]], meta=Meta [id=33]]
我使用自定义序列化器解决了这个问题,关闭了全局包装,然后根据 class 打开了包装。似乎即使您关闭全局包装,Jackson 也会为具有包装的 class 的列表元素添加包装。
与您的代码的一个区别是,对我来说,该列表由其自己的 class 包装。
事情是这样的:
@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();
}
}
我正在连载的class:
public class LogsDTO {
/** The logs. */
private List<LogDTO> logs;
/** Meta data. */
private Meta meta = new Meta();
// more
}
和生成的JSON:
{"LogsDTO":{"logs":[{"id":11,"archived":false}],"meta":{"totalPages":0}}}
我希望我的 JSON 看起来像:
{"logs":[{"id":11,"archived":false}],"meta":{"totalPages":0}}
有没有办法进行注释以便发生这种情况?
谢谢
@JsonRootName
:class 注释用于指示用于根值的 "wrapper" 条目的名称,如果启用了根包装。
杰克逊文档中说:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
相关Jira任务:http://jira.codehaus.org/browse/JACKSON-6301.9及以上版本支持
当调查 source code of @JsonRootName,
他们评论了 alwaysWrap 方法。
/* * Optional marker property that can be defined as
true
to force * wrapping of root element, regardless of whether globally * "root wrapping" is enabled or not. ** Note that value of
false
is taken to mean "use defaults", * and will not block use of wrapper if use is indicated by global features. * * @since 2.4 public boolean alwaysWrap() default false; */
他们计划在 v2.5 上激活它
As of 2.4, one missing feature is property "alwaysWrap", which is hoped * to be added in 2.5, and would be used to force root name wrapping * for individual types.
使用 Map<String, Object>
类型的地图。这个不是很好的解决方案不使用注释。我只想展示其他可能性如何避免 json 包装:
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);
}
产生:
{
"meta":{
"id":33
},
"logs":[
{
"id":1,
"archived":true
},
{
"id":2,
"archived":false
},
{
"id":3,
"archived":true
}
]
}
和
LogsDTO [logs=[Log [id=1, archived=true], Log [id=2, archived=false], Log [id=3, archived=true]], meta=Meta [id=33]]
我使用自定义序列化器解决了这个问题,关闭了全局包装,然后根据 class 打开了包装。似乎即使您关闭全局包装,Jackson 也会为具有包装的 class 的列表元素添加包装。 与您的代码的一个区别是,对我来说,该列表由其自己的 class 包装。 事情是这样的:
@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();
}
}