是否有杰克逊注释来抑制不必要的JSON包装?

时间:2015-04-17 10:45:50

标签: java json jackson

I班级序列化:

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

有没有办法进行注释以便发生这种情况?

由于

3 个答案:

答案 0 :(得分:2)

@JsonRootName:用于表示&#34;包装器&#34;的名称的类注释用于根值的条目,如果启用了根包装。

杰克逊博士说:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

相关的Jira任务:http://jira.codehaus.org/browse/JACKSON-630 1.9及以上版本支持它。

调查source code of @JsonRootName时,

他们评论了alwaysWrap方法。

  

/ *    *可选的标记属性,可以定义为强制true        *包装根元素,无论是否全局        *&#34; root wrap&#34;是否启用。        *

       *请注意,false的值代表&#34;使用默认值&#34;,        *如果全局功能指示使用,则不会阻止使用包装器。        *        * @since 2.4       public boolean alwaysWrap()默认为false;        * /

他们计划在v2.5上激活它

  

从2.4开始,一个缺少的功能是属性&#34; alwaysWrap&#34;,希望*在2.5中添加,并将用于强制各个类型的根名称包装*。

答案 1 :(得分:0)

使用Map<String, Object>类型的地图。这个不太好的解决方案不使用Annotation。我只是想表明如何避免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]]

答案 2 :(得分:0)

我使用自定义序列化程序解决了这个问题,关闭了全局包装,并打开了每个类的包装。似乎即使你把全局包装起来,杰克逊也会为包含类的列表元素添加包装。 与您的代码的一个区别是,对我来说,列表是由它自己的类包装的。 它是这样的:

    @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();
    }    
}