【问题标题】:Root element in JSON is coming twiceJSON 中的根元素将出现两次
【发布时间】:2015-04-10 13:59:56
【问题描述】:

我在 JSON 中获得了两次根元素。

这是我的模型:

@JsonRootName(value="volumes")
@XmlRootElement(name = "volumes")
public class VolumeDetails {

    @XmlElement(name = "volume")
    private List<VolumeDetail> volume;

    public List<VolumeDetail> getVolumes() {
        if (volume == null) {
             volume = new ArrayList<VolumeDetail>();
        }
        return volume;
    }

}

我正在使用杰克逊对象映射器,例如:

ObjectMapper om = new ObjectMapper().enable(SerializationConfig.Feature.WRAP_ROOT_VALUE);
try {
    String jsonResponse = om.writeValueAsString(volumeDetails);
    return Response.ok().entity(jsonResponse).build();
}

O/P:

{
   "volumes":{
      "volumes":[
         {
            "status":"available",
            "id":"vol-1"
         },
         {
            "status":"unavailable",
            "id":"vol-2"
         }
      ]
   }
}

预期的 O/P:

{
        "volumes":[
         {
            "status":"available",
            "id":"vol-1"
         },
         {
            "status":"unavailable",
            "id":"vol-2"
         }
      ]
}

volumes 标签来了两次,我不想要,有什么方法可以抑制它。 如果我删除@JsonRootName 注释和序列化功能,我得到的是“volume”而不是“volumes”,即@xmlElement(name="volume"),我的输出看起来像:

{
        "volume":[
         {
            "status":"available",
            "id":"vol-1"
         },
         {
            "status":"unavailable",
            "id":"vol-2"
         }
      ]
}

【问题讨论】:

    标签: json jaxb jackson


    【解决方案1】:

    来自SerializationFeature.WRAP_ROOT_VALUE 文档:

    可以启用将根值(通常是 JSON 对象,但可以是任何类型)包装在单个属性 JSON 对象中的功能,其中键作为“根名称”,由注释内省器确定(尤其是对于 JAXB使用@XmlRootElement.name)或回退(非限定类名)。该功能主要用于 JAXB 兼容性。

    功能默认禁用。

    还有@JsonRootName 文档:

    类似于 XmlRootElement 的注解,用于指示用于根级包装的名称,如果启用了包装。注解本身并不表示应该使用wrapping;但如果是,则用于序列化的名称应该是此处指定的名称,反序列化器也会期望该名称。

    所以,考虑这个例子:

    <!-- an old version of jackson which contains "SerializationConfig.Feature" -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    import org.codehaus.jackson.map.annotate.JsonRootName;
    
    @JsonRootName(value = "volumes")
    @XmlRootElement(name = "volumes")
    public class VolumeDetails {
    
        @XmlElement(name = "volume")
        private List<VolumeDetail> volume;
    
        public List<VolumeDetail> getVolumes() {
            if (volume == null) {
                volume = new ArrayList<>();
            }
            return volume;
        }
    
    }
    
    public class VolumeDetail {
    
        private String id;
        private String status;
    
        // getters and setters
    
    }
    
    public static void main(final String[] args) throws Exception {
        final VolumeDetails volumeDetails = new VolumeDetails();
    
        final VolumeDetail v1 = new VolumeDetail();
        v1.setId("vol-1");
        v1.setStatus("available");
        volumeDetails.getVolumes().add(v1);
    
        final VolumeDetail v2 = new VolumeDetail();
        v2.setId("vol-2");
        v2.setStatus("unavailable");
        volumeDetails.getVolumes().add(v2);
    
        final ObjectMapper om = new ObjectMapper();// .enable(SerializationConfig.Feature.WRAP_ROOT_VALUE);
        final String jsonResponse = om.writeValueAsString(volumeDetails);
        System.out.println(jsonResponse);
    }
    

    会生成这样的 JSON:

    {
       "volumes":[
          {
             "id":"vol-1",
             "status":"available"
          },
          {
             "id":"vol-1",
             "status":"unavailable"
          }
       ]
    }
    

    您可以从ObjectMapper 禁用SerializationFeature.WRAP_ROOT_VALUE

    【讨论】:

    • 如果我删除 @JsonRootName 注释和序列化功能,我得到的是“volume”而不是“volumes”。我已经添加了上面的 O/P。
    • @chandansingh 我更新了答案,看看。如果不起作用,现在让我。如果生成volume 看看VolumeDetails,也许你有getVolume 而不是getVolumes
    • @chandansingh 如果可行,请考虑接受答案 =)
    猜你喜欢
    • 1970-01-01
    • 2020-08-08
    • 2020-10-09
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2018-11-20
    • 2020-10-12
    • 1970-01-01
    相关资源
    最近更新 更多