解析 Json 数据。嵌套对象给出错误

Posted

技术标签:

【中文标题】解析 Json 数据。嵌套对象给出错误【英文标题】:Parsing Json data. Nested Objects giving an error 【发布时间】:2020-11-03 20:04:51 【问题描述】:

所以我有如下数据并且我正在尝试解析数据,但是我可以在网上看到很多关于解析 JSONArrays 的信息,而不是关于对象内的对象。我试了一下,但遇到了错误。这是我只想返回标记字段的 Json 响应:


    "geomagnetic-field-model-result": 
        "model": "wmm",
        "model_revision": "2020",
        "date": 
            "value": "2020-07-14"
        ,
        "coordinates": 
            "latitude": 
                "units": "deg (north)",
                "value": 0.0
            ,
            "longitude": 
                "units": "deg (east)",
                "value": 0.0
            ,
            "altitude": 
                "units": "km",
                "value": 0.00
            
        ,
        "field-value": 
            "total-intensity": 
                "units": "nT",
                "value": 123 //Return this*****************
            ,
            "declination": 
                "units": "deg (east)",
                "value": -123 //Return this*****************
            ,
            "inclination": 
                "units": "deg (down)",
                "value": 123 //Return this*****************
            ,
            "north-intensity": 
                "units": "nT",
                "value": 123
            ,
            "east-intensity": 
                "units": "nT",
                "value": -123
            ,
            "vertical-intensity": 
                "units": "nT",
                "value": 123
            ,
            "horizontal-intensity": 
                "units": "nT",
                "value": 123
            
        ,
        "secular-variation": 
            "total-intensity": 
                "units": "nT/y",
                "value": 123
            ,
            "declination": 
                "units": "arcmin/y (east)",
                "value": 123
            ,
            "inclination": 
                "units": "arcmin/y (down)",
                "value": 123
            ,
            "north-intensity": 
                "units": "nT/y",
                "value": 123
            ,
            "east-intensity": 
                "units": "nT/y",
                "value": 123
            ,
            "vertical-intensity": 
                "units": "nT/y",
                "value": 123
            ,
            "horizontal-intensity": 
                "units": "nT/y",
                "value": 123
            
        
    

我目前的解析尝试如下所示:

public void onResponse(JSONObject response) 
                        try 
                            JSONObject jsonObject = response;
                            String totalIntensity = jsonObject.getJSONObject("field-value").getJSONObject("total-intensity").getString("value");
                            String declination = jsonObject.getJSONObject("field-value").getJSONObject("declination").getString("value");
                            String inclination = jsonObject.getJSONObject("field-value").getJSONObject("inclination").getString("value");


                         catch (JSONException e) 
                            Log.d("geoData", "Error recorded");
                            e.printStackTrace();
                        
                    

我完全错了吗?希望这很容易让有人纠正我。

【问题讨论】:

【参考方案1】:

我假设您在方法中得到的响应是您在此处发布的整个 JSON 对象。

你有几个问题:

    您的数据不是 String,而是 DoubleInteger,因此您应该使用 getDouble 为例。 您忘记了一个额外的节点geomagnetic-field-model-result。 您无需分配内部JSONObject jsonObject,只需使用响应即可。

要达到你应该得到的值:

public void onResponse(JSONObject response) 
    try 
        // JSONObject jsonObject = response; you don't need this
        Double totalIntensity = response
            .getJSONObject("geomagnetic-field-model-result")
            .getJSONObject("field-value")
            .getJSONObject("total-intensity")
            .getDouble("value");
        Double declination = response
            .getJSONObject("geomagnetic-field-model-result")
            .getJSONObject("field-value")
            .getJSONObject("declination")
            .getDouble("value");
        Double inclination = response
            .getJSONObject("geomagnetic-field-model-result")
            .getJSONObject("field-value")
            .getJSONObject("inclination")
            .getDouble("value");

        // use it somehow
     catch (JSONException e) 
        Log.d("geoData", "Error recorded");
        e.printStackTrace();
    

【讨论】:

【参考方案2】:

创建一个 Schema 并使用返回值,它更容易使用 来自http://www.jsonschema2pojo.org/的返回响应的示例架构

    -----------------------------------com.example.Altitude.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Altitude 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Double value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Double getValue() 
return value;


public void setValue(Double value) 
this.value = value;



-----------------------------------com.example.Coordinates.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Coordinates 

@SerializedName("latitude")
@Expose
private Latitude latitude;
@SerializedName("longitude")
@Expose
private Longitude longitude;
@SerializedName("altitude")
@Expose
private Altitude altitude;

public Latitude getLatitude() 
return latitude;


public void setLatitude(Latitude latitude) 
this.latitude = latitude;


public Longitude getLongitude() 
return longitude;


public void setLongitude(Longitude longitude) 
this.longitude = longitude;


public Altitude getAltitude() 
return altitude;


public void setAltitude(Altitude altitude) 
this.altitude = altitude;



-----------------------------------com.example.Date.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Date 

@SerializedName("value")
@Expose
private String value;

public String getValue() 
return value;


public void setValue(String value) 
this.value = value;



-----------------------------------com.example.Declination.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Declination 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.Declination_.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Declination_ 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.EastIntensity.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class EastIntensity 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.EastIntensity_.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class EastIntensity_ 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.Example.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Example 

@SerializedName("geomagnetic-field-model-result")
@Expose
private GeomagneticFieldModelResult geomagneticFieldModelResult;

public GeomagneticFieldModelResult getGeomagneticFieldModelResult() 
return geomagneticFieldModelResult;


public void setGeomagneticFieldModelResult(GeomagneticFieldModelResult geomagneticFieldModelResult) 
this.geomagneticFieldModelResult = geomagneticFieldModelResult;



-----------------------------------com.example.FieldValue.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class FieldValue 

@SerializedName("total-intensity")
@Expose
private TotalIntensity totalIntensity;
@SerializedName("declination")
@Expose
private Declination declination;
@SerializedName("inclination")
@Expose
private Inclination inclination;
@SerializedName("north-intensity")
@Expose
private NorthIntensity northIntensity;
@SerializedName("east-intensity")
@Expose
private EastIntensity eastIntensity;
@SerializedName("vertical-intensity")
@Expose
private VerticalIntensity verticalIntensity;
@SerializedName("horizontal-intensity")
@Expose
private HorizontalIntensity horizontalIntensity;

public TotalIntensity getTotalIntensity() 
return totalIntensity;


public void setTotalIntensity(TotalIntensity totalIntensity) 
this.totalIntensity = totalIntensity;


public Declination getDeclination() 
return declination;


public void setDeclination(Declination declination) 
this.declination = declination;


public Inclination getInclination() 
return inclination;


public void setInclination(Inclination inclination) 
this.inclination = inclination;


public NorthIntensity getNorthIntensity() 
return northIntensity;


public void setNorthIntensity(NorthIntensity northIntensity) 
this.northIntensity = northIntensity;


public EastIntensity getEastIntensity() 
return eastIntensity;


public void setEastIntensity(EastIntensity eastIntensity) 
this.eastIntensity = eastIntensity;


public VerticalIntensity getVerticalIntensity() 
return verticalIntensity;


public void setVerticalIntensity(VerticalIntensity verticalIntensity) 
this.verticalIntensity = verticalIntensity;


public HorizontalIntensity getHorizontalIntensity() 
return horizontalIntensity;


public void setHorizontalIntensity(HorizontalIntensity horizontalIntensity) 
this.horizontalIntensity = horizontalIntensity;



-----------------------------------com.example.GeomagneticFieldModelResult.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class GeomagneticFieldModelResult 

@SerializedName("model")
@Expose
private String model;
@SerializedName("model_revision")
@Expose
private String modelRevision;
@SerializedName("date")
@Expose
private Date date;
@SerializedName("coordinates")
@Expose
private Coordinates coordinates;
@SerializedName("field-value")
@Expose
private FieldValue fieldValue;
@SerializedName("secular-variation")
@Expose
private SecularVariation secularVariation;

public String getModel() 
return model;


public void setModel(String model) 
this.model = model;


public String getModelRevision() 
return modelRevision;


public void setModelRevision(String modelRevision) 
this.modelRevision = modelRevision;


public Date getDate() 
return date;


public void setDate(Date date) 
this.date = date;


public Coordinates getCoordinates() 
return coordinates;


public void setCoordinates(Coordinates coordinates) 
this.coordinates = coordinates;


public FieldValue getFieldValue() 
return fieldValue;


public void setFieldValue(FieldValue fieldValue) 
this.fieldValue = fieldValue;


public SecularVariation getSecularVariation() 
return secularVariation;


public void setSecularVariation(SecularVariation secularVariation) 
this.secularVariation = secularVariation;



-----------------------------------com.example.HorizontalIntensity.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class HorizontalIntensity 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.HorizontalIntensity_.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class HorizontalIntensity_ 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.Inclination.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Inclination 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.Inclination_.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Inclination_ 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.Latitude.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Latitude 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Double value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Double getValue() 
return value;


public void setValue(Double value) 
this.value = value;



-----------------------------------com.example.Longitude.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Longitude 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Double value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Double getValue() 
return value;


public void setValue(Double value) 
this.value = value;



-----------------------------------com.example.NorthIntensity.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class NorthIntensity 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.NorthIntensity_.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class NorthIntensity_ 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.SecularVariation.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class SecularVariation 

@SerializedName("total-intensity")
@Expose
private TotalIntensity_ totalIntensity;
@SerializedName("declination")
@Expose
private Declination_ declination;
@SerializedName("inclination")
@Expose
private Inclination_ inclination;
@SerializedName("north-intensity")
@Expose
private NorthIntensity_ northIntensity;
@SerializedName("east-intensity")
@Expose
private EastIntensity_ eastIntensity;
@SerializedName("vertical-intensity")
@Expose
private VerticalIntensity_ verticalIntensity;
@SerializedName("horizontal-intensity")
@Expose
private HorizontalIntensity_ horizontalIntensity;

public TotalIntensity_ getTotalIntensity() 
return totalIntensity;


public void setTotalIntensity(TotalIntensity_ totalIntensity) 
this.totalIntensity = totalIntensity;


public Declination_ getDeclination() 
return declination;


public void setDeclination(Declination_ declination) 
this.declination = declination;


public Inclination_ getInclination() 
return inclination;


public void setInclination(Inclination_ inclination) 
this.inclination = inclination;


public NorthIntensity_ getNorthIntensity() 
return northIntensity;


public void setNorthIntensity(NorthIntensity_ northIntensity) 
this.northIntensity = northIntensity;


public EastIntensity_ getEastIntensity() 
return eastIntensity;


public void setEastIntensity(EastIntensity_ eastIntensity) 
this.eastIntensity = eastIntensity;


public VerticalIntensity_ getVerticalIntensity() 
return verticalIntensity;


public void setVerticalIntensity(VerticalIntensity_ verticalIntensity) 
this.verticalIntensity = verticalIntensity;


public HorizontalIntensity_ getHorizontalIntensity() 
return horizontalIntensity;


public void setHorizontalIntensity(HorizontalIntensity_ horizontalIntensity) 
this.horizontalIntensity = horizontalIntensity;



-----------------------------------com.example.TotalIntensity.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class TotalIntensity 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.TotalIntensity_.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class TotalIntensity_ 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.VerticalIntensity.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class VerticalIntensity 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



-----------------------------------com.example.VerticalIntensity_.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class VerticalIntensity_ 

@SerializedName("units")
@Expose
private String units;
@SerializedName("value")
@Expose
private Integer value;

public String getUnits() 
return units;


public void setUnits(String units) 
this.units = units;


public Integer getValue() 
return value;


public void setValue(Integer value) 
this.value = value;



所以现在随着架构没有改变,这将以正确的格式返回值

【讨论】:

其实你可以为coordinates,field-value,secular-variation中的每个属性使用同一个类 @TDIScott 所以我创建了所有这些类,我是否需要创建所有类来返回我需要的值?一旦我创建了这些,我应该在我的 onResponse 中添加什么? @HTBuild 一旦你有了 Schema,JSON 转换器会自动为你填充所有这些值。在您的情况下,您会看到顶部的“对象”geomagnetic-field-model-result 作为网络调用的 returnType。所以应该是public void onResponse(GeomagneticFieldModelResult response) @MarkiianBenovskyi 我同意这可以细化为一个通用类,因为每个Object的命名约定不会改变【参考方案3】:

你可以这样使用 Jackson:

import com.fasterxml.jackson.databind.ObjectMapper;

        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(input);
        System.out.println(jsonNode.get("geomagnetic-field-model-result").get("field-value").get("total-intensity").get("value"));

【讨论】:

这里的问题不在于是否使用 Jackson,而是 OP 在尝试获取其值时缺少一个额外的树节点 geomagnetic-field-model-result

以上是关于解析 Json 数据。嵌套对象给出错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Codable 解析嵌套的 JSON 数据

bigquery 嵌套对象:没有这样的字段

如何解析嵌套的json?迅速

解析 JSON 给出“意外的令牌 o”错误 [重复]

在 Dart/Flutter 中解析嵌套的 JSON

json解析出错误