Here's the code
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.ToString;
public class Main {
public static void main(String[] args) throws Exception {
Fields f1 = new Fields(1);
System.out.println(f1);
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(f1);
System.out.println(str);
Fields f2 = mapper.readValue(str, Fields.class);
System.out.println(f2);
}
@Data
@ToString
public static class Fields {
private final long value1;
private final long value2;
public Fields(@JsonProperty("blah") long value) {
this.value1 = value++;
this.value2 = value++;
System.out.println(this);
}
}
}
Output
Main.Fields(value1=1, value2=2)
Main.Fields(value1=1, value2=2)
{"value1":1,"value2":2}
Main.Fields(value1=0, value2=1)
Main.Fields(value1=1, value2=2)
My questions are:
Thank you
Why is it required that I annotate the constructor with @JsonProperty?
It's not. What is required is an accessible constructor. You can either have a parameterless constructor
public Fields() {
this.value1 = 0;
this.value2 = 0;
System.out.println("cons: " + this);
}
(that necessarily initializes the fields since they are final
) or you can have a constructor that Jackson will try to resolve based on the declared @JsonProperty
name. Note that JsonProperty#required
is false
by default.
Why did jackson modify private final fields that do not have setters after finish constructing it? If this is intended, how do I turn it off?
Because it can. It thus allows you to use immutable types with deserialization. There is no built-in way that I know of through which you can disable this feature.
Why did jackson modify private final fields that do not have setters after finish constructing it? If this is intended, how do I turn it off?
You can set MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS
property to false
(it is true
by default) when configuring your mapper.
Example:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Temp {
private static final String RAW = "{\"value1\": \"aabbcc\",\"value2\":\"zzzzz\"}";
public static void main(String[] args) throws Exception {
System.out.println(new ObjectMapper().readValue(RAW, TestClass.class));
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // you will receive UnrecognizedPropertyException without this line
mapper.configure(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS, false);
System.out.println(mapper.readValue(RAW, TestClass.class));
}
public static class TestClass {
private final String value1;
private final String value2;
@JsonCreator
public static TestClass createTestClass(
@JsonProperty("value1") String value1,
@JsonProperty("blah") String value2) {
return new TestClass(value1, value2);
}
private TestClass(String value1, String value2) {
this.value1 = value1;
this.value2 = value2;
}
public String getValue1() {
return value1;
}
public String getValue2() {
return value2;
}
@Override
public String toString() {
return "TestClass{" + "value1=" + value1 + ", value2=" + value2 + '}';
}
}
}
Output:
TestClass{value1=aabbcc, value2=zzzzz}
TestClass{value1=aabbcc, value2=null}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With