1

I'm trying to implement the global magnet API in an android application. I do a rest API get request and put the json API data in a string (this string is called dataString. This string looks like this:

{
  declination: {
  units: "Deg",
  value: -4.8235602378845215
  },
  inclination: {
  units: "Deg",
  value: -30.085556030273438
  },
  total_intensity: {
  units: "nT",
  value: 31945.123046875
  }
}

I'm now trying to deserialize this string into an object. I've made the following classes:

    public class MagneticData {
        @JsonProperty("declination")
        public MagneticDataElement declination;
        @JsonProperty("grid_variation")
        public MagneticDataElement grid_variation;
        @JsonProperty("inclination")
        public MagneticDataElement inclination;
        @JsonProperty("total_intensity")
        public MagneticDataElement total_intensity;
    }

    public class MagneticDataElement {
        @JsonProperty("units")
        public String units;
        @JsonProperty("value")
        public double value;
    }

I now use the ObjectMapper.readValue() function to convert the dataString to an object of the type MagneticData but i get the following error:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.mobcom.apitest.MainActivity$MagneticData: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)

What am i doing wrong?

  • 1
    Could you show your `POJO` classes like you really have them in a project: with all getters, setters and constructors? Exception message is pretty clear: `missing default constructor or creator, or perhaps need to add/enable type information?` means you do not have any public non argument constructor, or any other constructor which can be mapped to `JSON` easily. – Michał Ziober Dec 02 '19 at 23:04
  • Your `dataString` is not a valid JSON string because all the keys must be wrapped by double quotes and you don't have to add `@JsonProperty` to each field if the variable name and the key name of JSON object are identical. – LHCHIN Dec 03 '19 at 06:26

2 Answers2

0

I tested your code with revised JSON string and add toString() to your POJOs, everything works fine as follows, so maybe you have to provide more information for debugging such as how you deserialize it and which version of Jackson library you used.

Revised JSON string

{
  "declination": {
    "units": "Deg",
    "value": -4.8235602378845215
  },
  "inclination": {
    "units": "Deg",
    "value": -30.085556030273438
  },
  "total_intensity": {
    "units": "nT",
    "value": 31945.123046875
  }
}

Code snippet

ObjectMapper mapper = new ObjectMapper();
MagneticData magneticData = mapper.readValue(jsonStr, MagneticData.class);
System.out.println(magneticData.toString());

Console output

MagneticData [declination=MagneticDataElement [units=Deg, value=-4.8235602378845215], inclination=MagneticDataElement [units=Deg, value=-30.085556030273438], total_intensity=MagneticDataElement [units=nT, value=31945.123046875]]

LHCHIN
  • 3,679
  • 2
  • 16
  • 34
0

I'm using jackson version 2.8.5:

    implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.5'
    implementation 'com.fasterxml.jackson.core:jackson-core:2.8.5'
    implementation 'com.fasterxml.jackson.core:jackson-annotations:2.8.5'

This is my full code:

public class MainActivity extends AppCompatActivity {
    Button click;
    TextView data;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonPropertyOrder({
            "units",
            "value"
    })

    public class MagneticData {
        @JsonProperty("declination")
        public MagneticDataElement declination;
        @JsonProperty("grid_variation")
        public MagneticDataElement grid_variation;
        @JsonProperty("inclination")
        public MagneticDataElement inclination;
        @JsonProperty("total_intensity")
        public MagneticDataElement total_intensity;

        MagneticData(MagneticDataElement d, MagneticDataElement g, MagneticDataElement i, MagneticDataElement t) {
            declination = d;
            grid_variation = g;
            inclination = i;
            total_intensity = t;
        }
    }

    public class MagneticDataElement {
        @JsonProperty("units")
        public String units;
        @JsonProperty("value")
        public double value;

        MagneticDataElement(String u, double v) {
            units = u;
            value = v;
        }
    }


    public void deserialize(String str) throws IOException {

        //data.setText(jsonNode.get("total_intensity").textValue());
    }



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        click = findViewById(R.id.button);
        data = findViewById(R.id.fetchedData);

        click.setOnClickListener(new View.OnClickListener() {
            String dataString = "";
            @Override
            public void onClick(View v) {
                AsyncTask.execute(new Runnable() {
                    @Override
                    public void run() {
                        double altitude = 0;
                        double latitude = 0;
                        double longitude = 0;
                        double year = 2019;
                        URL url = null;
                        try {
                            url = new URL("https://globalmagnet.amentum.space/api/calculate_magnetic_field?altitude="+altitude+"&latitude="+latitude+"&longitude="+longitude+"&year="+year);
                            HttpsURLConnection myConnection = (HttpsURLConnection) url.openConnection();
                            myConnection.setRequestMethod("GET");
                            myConnection.setRequestProperty("Accept", "application/json");
                            if (myConnection.getResponseCode() == 200) {
                                Log.e("TYPE", myConnection.getContentType());
                                Log.e("Content", String.valueOf(myConnection.getInputStream()));
                                InputStream inputStream = myConnection.getInputStream();
                                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                                String line = "";
                                while (line != null) {
                                    line = bufferedReader.readLine();
                                    dataString = dataString + line;
                                }
                                Log.e("DATA", dataString);
                                MagneticData magneticData = new ObjectMapper().readValue(dataString, MagneticData.class);

                                runOnUiThread(new Runnable() {

                                    @Override
                                    public void run() {

                                    }
                                });

                            } else {
                                Log.e("ERROR", String.valueOf(myConnection.getResponseCode()));
                                Log.e("ERROR", myConnection.getResponseMessage());
                                Log.e("ERROR", String.valueOf(myConnection.getHeaderField("altitude")));

                            }
                        } catch (java.io.IOException e) {
                            e.printStackTrace();
                        }
                    }
                });

            }
        });



    }
}