133

I'm using GSON to convert JSON data I get to a Java object. It works pretty well in all my tests. The problem is that our real objects have some properties named like is_online. GSON only maps them if they are named totally equal, it would be nice to have GSON convert the names to Java camel case isOnline.

It seems this is possible while creating the JSON data, camel case is converted to underscore separated words in JSON. But I can't find a way to specify this the other way round.

bluish
  • 26,356
  • 27
  • 122
  • 180
Janusz
  • 187,060
  • 113
  • 301
  • 369

4 Answers4

375

I have found the following setting works perfect when reading json with underscored attributes and using camelcasing in my models.

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create()
Hampei
  • 3,838
  • 1
  • 18
  • 18
  • 2
    Great answer, thank you! @janusz, if any of these answers helped you, please mark them as Accepted Answer. – sufinawaz Dec 22 '14 at 22:08
  • 1
    If you have a case where the name contains two underscores, it ignores the first underscore. Ex. this_key_has__two_underscores will be converted to thisKeyHas_TwoUnderscores and the same vice versa. The key point is the FieldNamingPolicy where the enum says "lower case" with underscores while here the converted name has an upper case with underscore (_T). – Deepak G M May 13 '16 at 07:44
  • Very simple, saves me from having to annotate a bunch of fields! – William T. Mallard Sep 26 '17 at 19:25
  • where I need to put above code in spring boot application? In entity or DTO – Rajesh Patel Jun 16 '22 at 06:20
116

You can use the SerializedName annotation:

@SerializedName("field_name_in_json")
private final String fieldNameInJava;

Note: When you have set a FieldNamingPolicy already, SerializedName will overwrite its settings for that specific field (quite handy for special cases).

Brent Matzelle
  • 4,073
  • 3
  • 28
  • 27
saschoar
  • 8,150
  • 5
  • 43
  • 46
2

Bear in mind your example is an edge case. If you have a property 'foo' its getter should be named 'getFoo', and if you have a property named 'foo_bar' its getter should be named 'getFooBar', however, in your example you're mapping a boolean and booleans have special case naming conventions in java. A primitive boolean property named online should have a getter named 'isOnline', NOT 'getOnline' or even worse, 'getIsOnline'. A boolean wrapper object (i.e. Boolean) should not follow this special case and a property named 'online' should have a getter named 'getOnline'.

Hence, having boolean properties with 'is' in the name is an edge case, where you'll want to strip out this particular prefix during your conversion. In the reverse direction, your code may want to inspect the json object for both a raw property name as well as a 'is_XXX' version.

Jherico
  • 28,584
  • 8
  • 61
  • 87
2

I think what you want is here. Using annotations you can tell GSON that the mySuperCoolField is actually called this_field_is_fun in the JSON and it will unpack it correctly. At least I think it works for deserialization too.

If that doesn't work, you can use custom JsonSerializer/JsonDeserializers, which work great, but you have to update them for changes in your class (like when you add a field). You lose the auto-magic.

The easiest thing to do (which would be ugly, but very clean and simple if the first suggestion doesn't work) would be to simply name the field in a way to make GSON happy, and add extra accessor methods with the names you like, e.g.

public boolean isXXX() {return this.is_XXX;}
MBCook
  • 14,424
  • 7
  • 37
  • 41
  • the easy thing is what I'm doing at the moment and it works just fine. All the ugly not typical java styled code is hidden in the data classes and nobody from outside will see it. But it is still nagging me a little bit :) – Janusz Sep 09 '10 at 14:45