8

I am using feign for my rest-calls. Unfortunately one of the responses I get looks something like this:

{
    "customer-id" : "0123"
}

The JSON response automatically gets mapped to one of my POJO's. This response object can not have a property field with the name "customer-id", as the dash (-) is not allowed in the name of an identifier.

I tried the following:

public class LookUpAccountsResponse {
        @JsonProperty("customer-id")
        private String customerId;
}

But unfortunately this doesn't work. Does anyone have a suggestion on how to fix this?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Robert van der Spek
  • 1,017
  • 3
  • 16
  • 37
  • Where in the JSON specification does it say dashes aren't allowed? – OneCricketeer Apr 21 '17 at 08:05
  • 1
    What do you mean with a JSON specification? I know the JSON response has a - in its key ("customer-id"). The problem is to create a Java property field with a similar name (so it can be mapped). – Robert van der Spek Apr 21 '17 at 08:08
  • There's a standard definition for valid JSON keys http://json.org... I'm not sure what the error is, but the answer below suggests that the dash isn't the issue, so can you try to create a [mcve] like they have? – OneCricketeer Apr 21 '17 at 08:12
  • 1
    Thank God, we have StackOverflow. It saves me always – MaNn Apr 10 '20 at 13:39

4 Answers4

7

com.google.gson.GsonDecoder

Not sure why JsonProperty is on your classpath, but see "field naming support" https://github.com/google/gson/blob/master/UserGuide.md#json-field-naming-support

@SerializedName is the Gson annotation you'll want

Or switch entirely to using the feign-jackson dependency with a JacksonDecoder

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Finally, this worked for me. Added `@SerializedName` on top of the property which was having 'hypen' in their names. It looked like ` @JsonProperty("auth-key") @SerializedName("auth-key") private String authKey;`. I left the `@JsonProperty` annotation as it is as all other properties was having it. – Neeraj Singh Feb 26 '19 at 17:51
  • That would mean you have both Jackson and Gson on your classpath, which really is unncessary – OneCricketeer Feb 26 '19 at 20:27
  • 2
    I refactored and removed `@JsonProperty("auth-key")` which was completely unnecessary. WIll remove jackson from classpath if there is no other dependency in project. Meanwhile, after your comment, I revisited my module and added the following in my `application.yml` 1. `spring.http.converters.preferred-json-mapper= gson` and 2. `gson.field-naming-policy= LOWER_CASE_WITH_DASHES` as default strategy. Now, I didn't need to add `@SerializedName ("auth-key")` as the default strategy is taking care. – Neeraj Singh Mar 02 '19 at 19:05
5

It works fine. Here is a minimal example:

  public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
    SomeClass sc = new ObjectMapper().readValue("{\"property-with-dash\": 5}", SomeClass.class);

    System.out.println(sc.propertyWithDash);
  }

  public static class SomeClass {
    @JsonProperty("property-with-dash")
    private int propertyWithDash;
  }

This prints 5 as expected. No complaints.

john16384
  • 7,800
  • 2
  • 30
  • 44
0

Using JsonObjects and JsonArrays will allow you to get keys and values as Strings

codehacker
  • 381
  • 5
  • 15
0

You can use @JsonAlias.

It defines one or more alternative names for a property to be accepted during deserialization i.e. setting JSON data to Java object.

@JsonAlias("customer-id")

private String customerId;