Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|improve this question
Why are you making attributes into classes? – Joshua Wilson 1 hour ago
how is the binding done? which framework are you using? – gurvinder372 1 hour ago
The best solution would likely depend on the JSON marshaller you chose to use. Gson? Jackson? other? – JB Nizet 1 hour ago

3 Answers

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

share|improve this answer

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.

share|improve this answer

"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!!!

share|improve this answer
Sounds like my answer below :).. But no issues – guruprasath 49 mins ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.