I have a simple class with a private constructor and a static factory. I want the class to serialize as a number, so I annotated the getter for the field using @JsonValue . However, Jackson prefers a private constructor over a static factory, even when I set the static factory annotation with @JsonCreator . It works if I annotate a private constructor with @JsonIgnore , but that doesn't work a bit.
I saw several posts claiming that @JsonCreator only works if the parameters are annotated using @JsonProperty ; however, this is similar to objects serialized as JSON objects. This object is serialized as a number, and therefore there is no property for annotation.
Is there something I am missing?
class example:
package com.example; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import com.google.common.base.Preconditions; public class NonNegative { private final double n; private NonNegative(double n) { this.n = n; } @JsonCreator public static NonNegative checked(double n) { Preconditions.checkArgument(n >= 0.0); return new NonNegative(n); } @JsonValue public double getValue() { return n; } @Override public int hashCode() { return Objects.hash(n); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof NonNegative) { NonNegative that = (NonNegative) obj; return Objects.equals(n, that.n); } return false; } }
Test Examples:
package com.example; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class NonNegativeTest { private static final ObjectMapper MAPPER = new ObjectMapper(); @Test public void itSerializesAndDeserializes() throws Exception { NonNegative nonNegative = NonNegative.checked(0.5); assertThat(MAPPER.readValue(MAPPER.writeValueAsString(nonNegative), NonNegative.class)).isEqualTo(nonNegative); } @Test(expected = JsonMappingException.class) public void itDoesNotDeserializeANegativeNumber() throws Exception { MAPPER.readValue(MAPPER.writeValueAsString(-0.5), NonNegative.class); } }
java json jackson
NickAldwin
source share