当前位置: 首页 > 知识库问答 >
问题:

Android JSON无法从START_OBJECT反序列化ArrayList(JSON结构不正确)

淳于玺
2023-03-14

嗨,伙计们,我的客户端服务器出现了一些错误的JSON结构问题,我的客户机无法更改,我在这方面有处理。

我正在从JSON创建POJO,我已经尝试过GSON,现在我正在使用JACKSON,因为我认为JACKSON TREE会帮助我。

问题是服务器在只有一个对象时返回一个对象(扩展名),当它是几个对象时返回ArrayList。我知道这是一个糟糕的结构,为什么不返回一个带有1个对象的数组,但我什么也做不了。

在我的POJO类中,我想总是得到一个ArrayList换句话说,如果它只是数组的一个添加,则什么也不做。

JSON 示例:

    {
  "result": {
    "FeatureCollection": {
      "boundedBy": {
        "Envelope": {
          "lowerCorner": "-DUMMIE",
          "srsName": "DUMMIE",
          "upperCorner": "DUMMIE"
        }
      },
      "featureMember": [
        {
          "Spill": {
            "DUMMIE": "DUMMIE",
            "DUMMIE": "DUMMIE",
            "DUMMIE": "DUMMIE",
            "extension": {
              "Extension": {
                "area": 401994.1,
                "width": 288.6,
                "DUMMIE": "DUMMIE",
                "length": 2797,
              }
            },
            "DUMMIE": "DUMMIE",
            "DUMMIE": "DUMMIE",
          }
        },
        {
          "Spill": {
            "DUMMIE": "DUMMIE",
            "DUMMIE": "DUMMIE",
            "DUMMIE": "DUMMIE",
            "extension": [
              {
                "Extension": {
                  "area": 401994.1,
                  "width": 288.6,
                  "DUMMIE": "DUMMIE",
                  "length": 2797,
                }
              },
              {
                "Extension": {
                  "area": 401994.1,
                  "width": 288.6,
                  "DUMMIE": "DUMMIE",
                  "length": 2797,
                }
              }
            ],
            "DUMMIE": "DUMMIE",
            "DUMMIE": "DUMMIE",
          }
        }
      ],
      "xsi:schemaLocation": "DUMMIE",
      "numberOfFeatures": 10
    }
  },
  "status": "success"
}

问题出在POJO类

public class Spill {

@JsonProperty("dataSource")
private String dataSource;
@JsonProperty("timeStamp")
private String timeStamp;
@JsonProperty("SARWind_windIntensity")
private Double SARWindWindIntensity;
@JsonProperty("reliabilityIndex")
private Double reliabilityIndex;
@JsonProperty("meteoWind_dataType")
private String meteoWindDataType;
@JsonProperty("eventid")
private String eventid;
@JsonProperty("center")
private Center center;
@JsonProperty("area")
private Double area;
@JsonProperty("description")
private String description;
@JsonProperty("SARWind_windDirection")
private Long SARWindWindDirection;
@JsonProperty("name")
private String name;
@JsonProperty("meteoWind_dataSource")
private String meteoWindDataSource;
@JsonProperty("length")
private Double length;
@JsonProperty("meteoWind_windIntensity")
private Double meteoWindWindIntensity;
@JsonProperty("SARWind_dataSource")
private String SARWindDataSource;
@JsonProperty("SARWind_dataType")
private String SARWindDataType;
@JsonProperty("meteoWind_windDirection")
private Long meteoWindWindDirection;
@JsonProperty("imageIdentifier")
private ImageIdentifier imageIdentifier;
@JsonProperty("width")
private Double width;
@JsonProperty("origin")
private String origin;
@JsonProperty("extension")
private List<Extension> extension = new ArrayList<Extension>();
@JsonProperty("boundedBy")
private BoundedBy__ boundedBy;
@JsonProperty("auxiliaryDataRef")
private AuxiliaryDataRef auxiliaryDataRef;
@JsonProperty("gml:id")
private String gmlId;
@JsonProperty("alignedWithTrack")
private Boolean alignedWithTrack;
@JsonProperty("distanceFromCoast")
private Long distanceFromCoast;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

/**
 * 
 * @return The dataSource
 */
@JsonProperty("dataSource")
public String getDataSource() {
    return dataSource;
}

/**
 * 
 * @param dataSource
 *            The dataSource
 */
@JsonProperty("dataSource")
public void setDataSource(String dataSource) {
    this.dataSource = dataSource;
}

/**
 * 
 * @return The timeStamp
 */
@JsonProperty("timeStamp")
public String getTimeStamp() {
    return timeStamp;
}

/**
 * 
 * @param timeStamp
 *            The timeStamp
 */
@JsonProperty("timeStamp")
public void setTimeStamp(String timeStamp) {
    this.timeStamp = timeStamp;
}

/**
 * 
 * @return The SARWindWindIntensity
 */
@JsonProperty("SARWind_windIntensity")
public Double getSARWindWindIntensity() {
    return SARWindWindIntensity;
}

/**
 * 
 * @param SARWindWindIntensity
 *            The SARWind_windIntensity
 */
@JsonProperty("SARWind_windIntensity")
public void setSARWindWindIntensity(Double SARWindWindIntensity) {
    this.SARWindWindIntensity = SARWindWindIntensity;
}

/**
 * 
 * @return The reliabilityIndex
 */
@JsonProperty("reliabilityIndex")
public Double getReliabilityIndex() {
    return reliabilityIndex;
}

/**
 * 
 * @param reliabilityIndex
 *            The reliabilityIndex
 */
@JsonProperty("reliabilityIndex")
public void setReliabilityIndex(Double reliabilityIndex) {
    this.reliabilityIndex = reliabilityIndex;
}

/**
 * 
 * @return The meteoWindDataType
 */
@JsonProperty("meteoWind_dataType")
public String getMeteoWindDataType() {
    return meteoWindDataType;
}

/**
 * 
 * @param meteoWindDataType
 *            The meteoWind_dataType
 */
@JsonProperty("meteoWind_dataType")
public void setMeteoWindDataType(String meteoWindDataType) {
    this.meteoWindDataType = meteoWindDataType;
}

/**
 * 
 * @return The eventid
 */
@JsonProperty("eventid")
public String getEventid() {
    return eventid;
}

/**
 * 
 * @param eventid
 *            The eventid
 */
@JsonProperty("eventid")
public void setEventid(String eventid) {
    this.eventid = eventid;
}

/**
 * 
 * @return The center
 */
@JsonProperty("center")
public Center getCenter() {
    return center;
}

/**
 * 
 * @param center
 *            The center
 */
@JsonProperty("center")
public void setCenter(Center center) {
    this.center = center;
}

/**
 * 
 * @return The area
 */
@JsonProperty("area")
public Double getArea() {
    return area;
}

/**
 * 
 * @param area
 *            The area
 */
@JsonProperty("area")
public void setArea(Double area) {
    this.area = area;
}

/**
 * 
 * @return The description
 */
@JsonProperty("description")
public String getDescription() {
    return description;
}

/**
 * 
 * @param description
 *            The description
 */
@JsonProperty("description")
public void setDescription(String description) {
    this.description = description;
}

/**
 * 
 * @return The SARWindWindDirection
 */
@JsonProperty("SARWind_windDirection")
public Long getSARWindWindDirection() {
    return SARWindWindDirection;
}

/**
 * 
 * @param SARWindWindDirection
 *            The SARWind_windDirection
 */
@JsonProperty("SARWind_windDirection")
public void setSARWindWindDirection(Long SARWindWindDirection) {
    this.SARWindWindDirection = SARWindWindDirection;
}

/**
 * 
 * @return The name
 */
@JsonProperty("name")
public String getName() {
    return name;
}

/**
 * 
 * @param name
 *            The name
 */
@JsonProperty("name")
public void setName(String name) {
    this.name = name;
}

/**
 * 
 * @return The meteoWindDataSource
 */
@JsonProperty("meteoWind_dataSource")
public String getMeteoWindDataSource() {
    return meteoWindDataSource;
}

/**
 * 
 * @param meteoWindDataSource
 *            The meteoWind_dataSource
 */
@JsonProperty("meteoWind_dataSource")
public void setMeteoWindDataSource(String meteoWindDataSource) {
    this.meteoWindDataSource = meteoWindDataSource;
}

/**
 * 
 * @return The length
 */
@JsonProperty("length")
public Double getLength() {
    return length;
}

/**
 * 
 * @param length
 *            The length
 */
@JsonProperty("length")
public void setLength(Double length) {
    this.length = length;
}

/**
 * 
 * @return The meteoWindWindIntensity
 */
@JsonProperty("meteoWind_windIntensity")
public Double getMeteoWindWindIntensity() {
    return meteoWindWindIntensity;
}

/**
 * 
 * @param meteoWindWindIntensity
 *            The meteoWind_windIntensity
 */
@JsonProperty("meteoWind_windIntensity")
public void setMeteoWindWindIntensity(Double meteoWindWindIntensity) {
    this.meteoWindWindIntensity = meteoWindWindIntensity;
}

/**
 * 
 * @return The SARWindDataSource
 */
@JsonProperty("SARWind_dataSource")
public String getSARWindDataSource() {
    return SARWindDataSource;
}

/**
 * 
 * @param SARWindDataSource
 *            The SARWind_dataSource
 */
@JsonProperty("SARWind_dataSource")
public void setSARWindDataSource(String SARWindDataSource) {
    this.SARWindDataSource = SARWindDataSource;
}

/**
 * 
 * @return The SARWindDataType
 */
@JsonProperty("SARWind_dataType")
public String getSARWindDataType() {
    return SARWindDataType;
}

/**
 * 
 * @param SARWindDataType
 *            The SARWind_dataType
 */
@JsonProperty("SARWind_dataType")
public void setSARWindDataType(String SARWindDataType) {
    this.SARWindDataType = SARWindDataType;
}

/**
 * 
 * @return The meteoWindWindDirection
 */
@JsonProperty("meteoWind_windDirection")
public Long getMeteoWindWindDirection() {
    return meteoWindWindDirection;
}

/**
 * 
 * @param meteoWindWindDirection
 *            The meteoWind_windDirection
 */
@JsonProperty("meteoWind_windDirection")
public void setMeteoWindWindDirection(Long meteoWindWindDirection) {
    this.meteoWindWindDirection = meteoWindWindDirection;
}

/**
 * 
 * @return The imageIdentifier
 */
@JsonProperty("imageIdentifier")
public ImageIdentifier getImageIdentifier() {
    return imageIdentifier;
}

/**
 * 
 * @param imageIdentifier
 *            The imageIdentifier
 */
@JsonProperty("imageIdentifier")
public void setImageIdentifier(ImageIdentifier imageIdentifier) {
    this.imageIdentifier = imageIdentifier;
}

/**
 * 
 * @return The width
 */
@JsonProperty("width")
public Double getWidth() {
    return width;
}

/**
 * 
 * @param width
 *            The width
 */
@JsonProperty("width")
public void setWidth(Double width) {
    this.width = width;
}

/**
 * 
 * @return The origin
 */
@JsonProperty("origin")
public String getOrigin() {
    return origin;
}

/**
 * 
 * @param origin
 *            The origin
 */
@JsonProperty("origin")
public void setOrigin(String origin) {
    this.origin = origin;
}

/**
 * 
 * @return The extension
 */
@JsonProperty("extension")
public List<Extension> getExtension() {
    return extension;
}

/**
 * 
 * @param extension
 *            The extension
 */
@JsonProperty("extension")
public void setExtension(List<Extension> extension) {
    this.extension = extension;
}

/**
 * 
 * @return The boundedBy
 */
@JsonProperty("boundedBy")
public BoundedBy__ getBoundedBy() {
    return boundedBy;
}

/**
 * 
 * @param boundedBy
 *            The boundedBy
 */
@JsonProperty("boundedBy")
public void setBoundedBy(BoundedBy__ boundedBy) {
    this.boundedBy = boundedBy;
}

/**
 * 
 * @return The auxiliaryDataRef
 */
@JsonProperty("auxiliaryDataRef")
public AuxiliaryDataRef getAuxiliaryDataRef() {
    return auxiliaryDataRef;
}

/**
 * 
 * @param auxiliaryDataRef
 *            The auxiliaryDataRef
 */
@JsonProperty("auxiliaryDataRef")
public void setAuxiliaryDataRef(AuxiliaryDataRef auxiliaryDataRef) {
    this.auxiliaryDataRef = auxiliaryDataRef;
}

/**
 * 
 * @return The gmlId
 */
@JsonProperty("gml:id")
public String getGmlId() {
    return gmlId;
}

/**
 * 
 * @param gmlId
 *            The gml:id
 */
@JsonProperty("gml:id")
public void setGmlId(String gmlId) {
    this.gmlId = gmlId;
}

/**
 * 
 * @return The alignedWithTrack
 */
@JsonProperty("alignedWithTrack")
public Boolean getAlignedWithTrack() {
    return alignedWithTrack;
}

/**
 * 
 * @param alignedWithTrack
 *            The alignedWithTrack
 */
@JsonProperty("alignedWithTrack")
public void setAlignedWithTrack(Boolean alignedWithTrack) {
    this.alignedWithTrack = alignedWithTrack;
}

/**
 * 
 * @return The distanceFromCoast
 */
@JsonProperty("distanceFromCoast")
public Long getDistanceFromCoast() {
    return distanceFromCoast;
}

/**
 * 
 * @param distanceFromCoast
 *            The distanceFromCoast
 */
@JsonProperty("distanceFromCoast")
public void setDistanceFromCoast(Long distanceFromCoast) {
    this.distanceFromCoast = distanceFromCoast;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
    return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
    this.additionalProperties.put(name, value);
}

}

我尝试过的:GSON:

CnsDetection cnsDetection = gson.fromJson(json, CnsDetection.class);

杰克逊

    ObjectMapper mapper = new ObjectMapper();
cnsDetection = mapper.readValue(json, CnsDetection.class);

尝试使用自定义反序列化,但没有运气。我的主要问题是如何将特定的节点从object改为arrayList,然后如何创建包含溢出对象的CnsDetection对象。

还看过:-如何使用Gson动态处理json响应数组/对象- GSON期望BEGIN_ARRAY但却是BEGIN_OBJECT

更新

我已经尝试了@vzamanillo的答案,但我遇到了几个错误,但这个答案让我走上了正确的道路,并且是我的问题的正确答案。PS:正如他在这里问的那样,这是我的ExtensionDeserializer:

注意:jacksonHelper是一个单独的,所以我可以在应用程序中重用映射器。

不工作的反序列化程序

public class ExtensionDeserializer extends JsonDeserializer<List<Extension>> {
JacksonHelper jacksonHelper = JacksonHelper.getInstance();

@Override
public List<Extension> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
    ObjectCodec oc = jsonParser.getCodec();
    JsonNode node = oc.readTree(jsonParser);
    List<Extension> result = new ArrayList<Extension>();

    if (node.isObject()) {
        result =
                jacksonHelper.getMapper().convertValue(node,
                        jacksonHelper.getMapper().getTypeFactory().constructCollectionType(List.class, Extension.class));
    }
    if (node.isArray()) {
        result.add(jsonParser.readValueAs(Extension.class));
    }
    return result;
}}

工作反序列化器信用到:@vzamanillo

public class ExtensionDeserializer extends JsonDeserializer<List<Extension>> {
JacksonHelper jacksonHelper = JacksonHelper.getInstance();

@Override
public List<Extension> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
    ObjectCodec oc = jsonParser.getCodec();
    JsonNode node = oc.readTree(jsonParser);
    List<Extension> result = new ArrayList<Extension>();

    if (node.isObject()) {
        result.add(jacksonHelper.getMapper().treeToValue(node, Extension.class));
    }
    if (node.isArray()) {
        result = jacksonHelper.getMapper().readValue(node.traverse(), new TypeReference<List<Extension>>() {
        });
    }
    return result;
}}

共有3个答案

游勇军
2023-03-14

我认为问题在于解析“扩展”数组。由于它也是一个数组,您应该在模型类中为其内容创建一个新的内部类:

public static class Extension {
    @JsonProperty("area")
    private Double area;
    @JsonProperty("width")
    public String width;
    @JsonProperty("length")
    public String length;

并且比生成其设置器和获取器。为了更清楚地说明这一点,我将粘贴一个代码段,用于JSON的以下情况:

{
"table_name":"bbbb",
"table_version":1,
"table_data":[
             {
              "OPERATION":"aaaa",
              "TRANSACTION_ID":1
             }
             ]
}

为了解析这种JSON,我使用了上面粘贴的模型;在我的例子中,table_date是内部类。

问候

任繁
2023-03-14

在JSON结构的第一部分,“扩展”包含一个对象,但在第二个实例中,您有一个对象数组。

即使您有一个对象,如果您可能有多个对象,您也应该始终使用数组来保持结构。

陆琦
2023-03-14

为< code>extension属性创建自定义的< code>JsonDeserializer,并检查节点类型是数组还是对象,如果节点是对象,则将其添加到返回列表中。

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;

    import org.codehaus.jackson.JsonNode;
    import org.codehaus.jackson.JsonParser;
    import org.codehaus.jackson.ObjectCodec;
    import org.codehaus.jackson.map.DeserializationContext;
    import org.codehaus.jackson.map.JsonDeserializer;
    import org.codehaus.jackson.map.ObjectMapper;

    class ExtensionDeSerializer extends JsonDeserializer<List<Extension>> {
        @Override
        public List<Extension> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
            ObjectCodec oc = jsonParser.getCodec();
            JsonNode node = oc.readTree(jsonParser);
            List<Extension> result = new ArrayList<Extension>();
            if (node.isObject()) {

                ObjectMapper mapper = new ObjectMapper();
                // @firetrap less obscure and better solution
                //result.add(jacksonHelper.getMapper().treeToValue(node, Extension.class));

                result = mapper.convertValue(node, mapper.getTypeFactory().constructCollectionType(List.class, Extension.class));
            }
            if (node.isArray()) {
                result.add(jsonParser.readValueAs(Extension.class));
            }
            return result;
        }
    }

将< code>@JsonDeserialize批注添加到POJO类的< code>extension属性中。

@JsonDeserialize(using=ExtensionDeSerializer.class)
@JsonProperty("extension")
private List<Extension> extension = new ArrayList<Extension>();

当属性可以是对象或数组时,这可能是解决问题的最有效方法。

希望这有帮助。

 类似资料:
  • 我以前从未使用过JSON,我想序列化

  • 当然,所有依赖项(子类追加在同一个字符串中)。 从外部API获取数据的代码是; 当我运行代码并试图获取adress“API/3”时,出现以下错误:

  • 问题内容: 我试图序列化和反序列化内部对象的数组列表: HairList对象也是一个可序列化的对象。 此代码执行返回以下错误: 排队 我不知道我在做什么错。你能给个小费吗? 更新: 解决: 仅使用HairBirt的本机数组而不是ArrayList即可工作: 代替 感谢大家的帮助。 问题答案: 不要使用-而是使用二进制数据并对它进行base64编码,以将其转换为字符串而不会丢失信息。 我强烈怀疑这是

  • 我试图读取这个json值并将其转换为java对象

  • 我是一个新手,正在尝试编写一个简单的应用程序,从大学校中提取一些学校数据。组织。json数据如下所示: 我的结构如下所示: 当我运行代码时,我得到“json:无法将对象解组为[]main.SchoolStruct类型的Go值” 我正在使用gopencils库来提出我的请求,并成功地将其用于非常简单的请求。你知道我可能做错了什么吗?

  • 问题内容: 我有可以访问所有国家/地区的休息网址-http://api.geonames.org/countryInfoJSON ?username=volodiaL。 我从春季3开始使用RestTemplate将返回的json解析为java对象: 当我运行此代码时,出现异常: 最后是我的国家/地区课程: 问题是返回的json包含根元素“ geonames”,其中包含国家元素数组,如下所示: 如何