Java - What to do when JSON can come in Double and Long?

Asked

Viewed 252 times

1

I am using a Climatempo API.

When I get the weather data of a city via JSON I get the temperature as follows:

clima.setTemperatura((Long) dataNode.get("temperature"))

However, in the API documentation, when I use get("temperature") it can return me a value "20" or a value "27.4" in an Object type. This value is in degrees Celsius.

I’m having an exception in java that says (depending) that:

Double cannot be converted to Long

The attribute temperatura with the guy Longis in my Clima.java class, I have defined since when I created the class and created the data types in the database. So I CAN NOT switch to String, because I will use this data for statistical purposes.

What should I do to make the treatment if it comes "20" (Long) or "27.4" it does not cause these exceptions?

EDITION As requested in the comments, I will add more details.

I use the following method to access the API:

    @GetMapping("/clima/{idCidade}/agora")
    public ResponseEntity<Clima> getClimaAgora(@PathVariable(value = "idCidade") Long idCidade){
        JSONObject climateData = new JSONObject();
        ClimaTempoAPI ct = new ClimaTempoAPI();
        String weatherEndpoint = "/api/v1/weather/locale/"+idCidade+"/current?";
        climateData = ct.RequestWeather(weatherEndpoint);

        JSONObject dataNode = (JSONObject) climateData.get("data");     

        Clima clima = new Clima();
        clima = setClimateData(climateData, dataNode, clima);
        climaRepository.save(clima);        

        return ResponseEntity.ok().body(clima);
    }

The error is happening in the method setClimateData which has the following implementation in the same class:

public Clima setClimateData(JSONObject climateData, JSONObject dataNode, Clima clima){
   clima.setVelVento((Long) dataNode.get("wind_velocity"));
   clima.setDirVento((String) dataNode.get("wind_direction"));
   (...)
   clima.setTemperatura((Long) dataNode.get("temperature")  ); //Erro acontece aqui
}

All the others sets work without any problem. Only in this temperature it gives error, as can come both an integer number and decimal.

I tried using Numeric but it just won’t. It says it can’t be a type.

I have tried some things. How to convert from Double to Long. Take Object and convert to String (at the time of saving in the error database - I am using Spring Boot with JPA and Hibernate). It’s just not getting what I want...

  • Cast for double only?

  • And wouldn’t it be better to start keeping this data as Double ?

  • Wouldn’t it be better to sit and cry? Anyway, the return for what he speaks extends to Numeric, then it is possible to give a ((Numeric) node.get("temperature")).asDouble()

  • How so a double can not be converted to long? Ever tried Double.valueOf("27.4").longValue()? Of course the value will be rounded to 27 (since long has no decimal places), but it works. If you can [Dit] the question and add examples of cases that gives this error, maybe it becomes clearer (in other words, a [mcve]).

  • 1

    I will edit the question and add more details. I tried to be as brief as possible, but you will need more details for what I am seeing.

  • @Witnesstruth I think you can treat as Numeric, both Double and Long inherited from him. Then the transformation is free, with the method .doubleValue() or .longValue(), as hkotsubo very well spoke

  • It won’t, if I put it the way hkotsubo said, it simply says "Numeric cannot be resolved to a type"

  • And if it is Number? https://docs.oracle.com/javase/7/docs/api/java/Long.html My name is wrong, I’m sorry....

  • Which of the thousands of JSON Apis are you using? You have no method getLong(), for example?

  • @hkotsubo looks like Jsonsimple, but I’m not sure

  • If get returns a Object, maybe Double.valueOf(node.get("temperature").toString()).longValue() work as well. Although the answer from Victor below should solve

Show 6 more comments

1 answer

4


You can use the instanceof to find out if it is Double or Long and then choose how to treat:

Object temperaturaObj = dataNode.get("temperature");
Long temperatura = temperaturaObj == null ? null
        : temperaturaObj instanceof Long ? (Long) temperaturaObj
        : ((Double) temperaturaObj).longValue();
clima.setTemperatura(temperatura);

Should you decide to switch to Double instead of Long:

Object temperaturaObj = dataNode.get("temperature");
Long temperatura = temperaturaObj == null ? null
        : temperaturaObj instanceof Double ? (Double) temperaturaObj
        : ((Long) temperaturaObj).doubleValue();
clima.setTemperatura(temperatura);

Or else, use the superclass Number with a cast:

Number temperatura = (Number) dataNode.get("temperature");
clima.setTemperatura(temperatura == null ? null : temperatura.longValue());
  • Why not Number, the mother class of Long and of Double?

  • 1

    @Jeffersonquesado Why in the setTemperatura, the type of the parameter is Long. Since he’s using this for JPA mapping, it’s not usable Number, have to choose between Long and Double (or BigDecimal or Integer or BigInteger, etc). But you can’t make it flexible in JPA.

  • Number.class.cast(dataNode.get("temperature")).longValue() or .doubleValue(). In this use, not for the type to be set

  • @Jeffersonquesado You can make it simpler than that without using the object class. I edited the answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.