4
votes

I am making an external call via RestTemplate as follows:

ResponseEntity<Response> response = template.exchange("some.endpoint.com", HttpMethod.POST, request, MyClass.class);

The API returns a boolean value in String format as follows: ("0" or "1")

{
    "some_lengthy_key_name" : "1"
}

I am trying to map this response to the following class.

@Getter
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder
public class MyClass{
    @JsonProperty("some_lengthy_key_name")
    private final boolean isValid;
}

It looks like Jackson doesn't entertain this and throws following error (understandable):

Can not deserialize value of type boolean from String "1" only "true" or "false" recognized.

I don't want to go down the route of capturing it as a String and then modifying value after. Instead prefer to go for the option of getting a custom deserialization going and went for the following:

public class Deserializer extends JsonDeserializer<Boolean> {
    @Override
    public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        return !"0".equals(parser.getText());
    }
}

I've now annotated the field in MyClass as follows:

@Getter
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder
public class MyClass{
    @JsonDeserialize(using = Deserializer.class)
    @JsonProperty("some_lengthy_key_name")
    private final boolean isValid
}

But unfortunately this is not working either and throwing same error. Could I get some advice as to what I am doing wrong with this custom deserialization? Thanks.

2
Try with Boolean instead of booleanCodeScale
@CodeScale Doesn't make a diff with Boolean.karvai

2 Answers

2
votes

You don't need any custom deserializer for this, just override the property with custom setter method and then annotated that method with @JsonProperty. Another note jackson uses getters and setters for serialization and deserialization so you cannot declare variables as final

@Getter
@Setter
class MyClass{

   private boolean isValid;

   @JsonProperty("some_lengthy_key_name")
   public void setIsValid(String value) {
      isValid = "1".equals(value);
   }
}

There is another way in jackson for deserializing using constructor to prevent immutability of object, check this for more information

@Getter
@Setter
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public class MyClass{

   private final boolean isValid;

   public MyClass(@JsonProperty("some_lengthy_key_name") String name) {
      this.isValid = "1".equals(name);
}
0
votes

You can not use final, and use a Boolean type instead of boolean

@Getter
@Setter
public class MyClass{
    @JsonDeserialize(using = Deserializer.class)
    @JsonProperty("some_lengthy_key_name")
    private Boolean isValid; //<= You did not use final, and use Boolean type instead of boolean
}