Open jonjanisch opened 1 year ago
@cowtowncoder is there any updates on this?
@Taz03 come on - your comments go to lots of people. Do you really need to spam everyone every 3 hours?
@JsonUnwrapped
does not work with Constructor-based deserialization. There is an earlier issue #1467 that covers it.
@Taz03 If there was an update, it would be noted here. There isn't, hasn't been, and no immediate progress in sight.
you can customize a deserilaizer
@JsonDeserialize(using = TestDeserializer.class)
public record TestRecord(String name, @JsonUnwrapped Address address) {}
static class TestDeserializer extends JsonDeserializer<TestRecord> {
@Override
public TestRecord deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JacksonException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String name = node.get("name").asText();
String city = node.get("city").asText();
String state = node.get("state").asText();
return new TestRecord(name, new Address(city, state));
}
}
ObjectMapper objectMapper = new ObjectMapper();
String json = "{\"name\":\"Bob\",\"city\":\"New York\",\"state\":\"NY\"}";
System.out.println(objectMapper.readValue(json, TestRecord.class));
// TestRecord[name=Bob, address=Address[city=New York, state=NY]]
Or, use @JsonCreator
and @JsonProperty
public record TestRecord(String name, @JsonUnwrapped @JsonProperty(access = Access.READ_ONLY) Address address) {
@JsonCreator
public TestRecord(@JsonProperty("name") String name, @JsonProperty("city") String city,
@JsonProperty("state") String state) {
this(name, new Address(city, state));
}
}
ObjectMapper objectMapper = new ObjectMapper();
String json = "{\"name\":\"Bob\",\"city\":\"New York\",\"state\":\"NY\"}";
System.out.println(objectMapper.readValue(json, TestRecord.class));
// TestRecord[name=Bob, address=Address[city=New York, state=NY]]
As I spent quite some time to find a solution that fits my case, it's not more than right to share it here. In my case the "address" is a more complex object and handing the fields manually was not an option for me.
This is similar to what I ended up with, based on the example record above:
public record TestRecord(
String name,
@JsonUnwrapped Address address
) {
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public TestRecord(JsonNode node) {
this(
ObjectMapperHolder.getObjectMapper().convertValue(node.get("name"), String.class),
ObjectMapperHolder.getObjectMapper().convertValue(node, Address.class)
);
}
}
Actually there might be way forward for this, see #4271.
Just use builder as deserializer will fix this.
@Builder
@Jacksonized
public record TessRecord (
String name,
@JsonUnwrapped
Address address
) {}
I'm attempting to deserialize JSON into a simple Java record where one of the members, a simple POJO, is annotated as
@JsonUnwrapped
.If I attempt to deserialize the JSON string
{"name":"Bob","city":"New York","state":"NY"}
, I get the exception:Version information Tested both 2.13.2 and 2.14.1 - same problem with both versions.
To Reproduce This uses JDK17 multiline string but trivial to replace with escaped string.
Additional context If I change TestRecord to a plain Java class, it works fine.
I've tried using the annotations
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
and annotating all fields with@JsonProperty
to no avail.