简体   繁体   中英

How to map Json to Java classes when some variable names begin with a number?

Recently I've been playing with a webservice that returns a json object like this

{
  "id": 88319,
  "dt": 1345284000,
  "name": "Benghazi",
  "coord": {
    "lat": 32.12,
    "lon": 20.07
  },
  "main": {
    "temp": 306.15,
    "pressure": 1013,
    "humidity": 44
  },
  "wind": {
    "speed": 1,
    "deg": -7
  },
  "clouds": {
    "all": 90
  },
  "rain": {
    "3h": 3
  }
}

I have automatically generated Java classes mapping to that json data. The problem is I cannot generate a Java class with an attribute named 3h (in Java as in many other languages variable identifiers cannot begin with a number). As a hack around I have redefined the attribute 3h as h3 , and whenever I receive a json response from the web service I replace the string "3h" by "h3".

However, that approach is only appropriate for small projects. I would like to know if there is a more convenient approach to deal with this kind of situation.

Notes: For this particular example I used an online tool that generated the java classes given a json example. In other situations I have used Jackson, and other frameworks. ¿Is the answer to this question framework dependent? To be more concrete, and having the future in mind, I would like to adhere to the json-schema specification

If using Gson you can do it with @SerializedName annotation.

Java Class:

public class JsonData {

    @SerializedName("3h")
    private int h3;

    private String name;

    public JsonData(int h3, String name) {
        this.h3 = h3;
        this.name = name;
    }

}

Serialization: (same class works for fromJson() as well)

// prints: {"3h": 3,"name": "Benghazi"}
System.out.println(new Gson().toJson(new JsonData(3, "Benghazi")));

Reference:
@SerializedName Annotation

You can prefix the data type of the property you are generating. Like arr_,int_,obj_ etc for respective objects because during autogeneration, you will anyway have to deal with the datatype. This will become a general fix rather than specifically looking for strings like "3h". But design-wise or good-practice wise this might not be the most optimal solution.

"I would like to know if there is a more convenient approach to deal with this kind of situation."

Firstly I can not make out what "this kind of situation" is since you have not mentioned the frameworks or approach by which you are making the mapping.

And if you want to have the attribute identifiers mapping to your json keys, to begin with numbers, it is not possible and that too is for good only.

Since,say for example if your last subdocument:

"rain": {
    "3h": 3
  }

is mapped to a class Rain as:

class Rain{
   int 3h=3
}

Then how will you parse the variable assignment "3h=3" ?(Refer this SO post)

So what I can think of a way is that maybe you can prefix any keys starting with numbers with special legal identifier charatcers (like "_" underscore) and later on remove the assignment.

Which means, you can map your json subdocument rain as:

class Rain{
   int _3h=3
}

And later remove the leading underscore while deserializing.

Hope that helps!!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM