JsonMapper readValue not mapping byte[] object to POJO class #344
-
|
Good day! We are experiencing serialize/deserialize issue during our SpringBoot/Jackson migration of our service. This used to work back in spring-boot 3.5.9/jackson 2, but started becoming an issue when we migrated to spring-boot 4.0.0/jackson 3. For this post, I'll just focus on the deserialize part as solution may also resolve issue encountered with serializing ( This is the IndividualDetails and IndividualName openapi generated POJO classes: IndividualDetails.class @JsonPropertyOrder({
IndividualResponse.JSON_PROPERTY_INDIVIDUAL_NAME,
IndividualResponse.JSON_PROPERTY_CUSTOMER_ID
})
@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
@com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown=true)
@lombok.Data
@lombok.Builder
@lombok.AllArgsConstructor
@jakarta.annotation.Generated(value = "...", comments = "Generator version: 7.19.0")
public class IndividualResponse implements Serializable {
private static final long serialVersionUID = 1L;
public static final String JSON_PROPERTY_INDIVIDUAL_NAME = "individualName";
@jakarta.annotation.Nullable
private IndividualName individualName;
/**
* Get individualName
* @return individualName
*/
@jakarta.annotation.Nullable
@JsonProperty(value = JSON_PROPERTY_INDIVIDUAL_NAME, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public IndividualName getIndividualName() {
return individualName;
}
@JsonProperty(value = JSON_PROPERTY_INDIVIDUAL_NAME, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public void setIndividualName(@jakarta.annotation.Nullable IndividualName individualName) {
this.individualName = individualName;
}
...
...IndividualName.class /**
* IndividualName
*/
@JsonPropertyOrder({
IndividualName.JSON_PROPERTY_LAST_NAME,
IndividualName.JSON_PROPERTY_FIRST_NAME1,
IndividualName.JSON_PROPERTY_FIRST_NAME2
})
@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
@com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown=true)
@lombok.Data
@lombok.Builder
@lombok.AllArgsConstructor
@jakarta.annotation.Generated(value = "...", comments = "Generator version: 7.19.0")
public class IndividualName implements Serializable {
private static final long serialVersionUID = 1L;
public static final String JSON_PROPERTY_LAST_NAME = "lastName";
@jakarta.annotation.Nullable
private String lastName;
public static final String JSON_PROPERTY_FIRST_NAME1 = "firstName1";
@jakarta.annotation.Nullable
private String firstName1;
public static final String JSON_PROPERTY_FIRST_NAME2 = "firstName2";
@jakarta.annotation.Nullable
private String firstName2;
public IndividualName() {
}
public IndividualName lastName(@jakarta.annotation.Nullable String lastName) {
this.lastName = lastName;
return this;
}
/**
* Get lastName
* @return lastName
*/
@jakarta.annotation.Nullable
@JsonProperty(value = JSON_PROPERTY_LAST_NAME, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public String getLastName() {
return lastName;
}
@JsonProperty(value = JSON_PROPERTY_LAST_NAME, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public void setLastName(@jakarta.annotation.Nullable String lastName) {
this.lastName = lastName;
}
public IndividualName firstName1(@jakarta.annotation.Nullable String firstName1) {
this.firstName1 = firstName1;
return this;
}
/**
* Get firstName1
* @return firstName1
*/
@jakarta.annotation.Nullable
@JsonProperty(value = JSON_PROPERTY_FIRST_NAME1, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public String getFirstName1() {
return firstName1;
}
@JsonProperty(value = JSON_PROPERTY_FIRST_NAME1, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public void setFirstName1(@jakarta.annotation.Nullable String firstName1) {
this.firstName1 = firstName1;
}
public IndividualName firstName2(@jakarta.annotation.Nullable String firstName2) {
this.firstName2 = firstName2;
return this;
}
/**
* Get firstName2
* @return firstName2
*/
@jakarta.annotation.Nullable
@JsonProperty(value = JSON_PROPERTY_FIRST_NAME2, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public String getFirstName2() {
return firstName2;
}
@JsonProperty(value = JSON_PROPERTY_FIRST_NAME2, required = false)
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public void setFirstName2(@jakarta.annotation.Nullable String firstName2) {
this.firstName2 = firstName2;
}
...
...This is our JsonMapper configuration: JsonMapper objectMapper = JsonMapper.builder()
.changeDefaultPropertyInclusion(incl ->
incl.withValueInclusion(JsonInclude.Include.NON_NULL)
)
.disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
.disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
.build();When we try to log the byte[] content (converted to string), we get the correct value: byte[] idvState = idvCase.getIndividualDetails(); // individualDetails is a BLOB byte[] field
log.info("ID&V Case: [{}] - [{}] - [{}]",
idvCase.getCaseId(), idvCase.getCaseStatus(), new String(idvState, StandardCharsets.UTF_8));
DISPLAYS:
ID&V Case: [CASE-484] - [CLOSED_SUCCESS] - [{"individualName":{"lastName":"Doe","firstName1":"John","firstName2":"Mayer"},...,"customerId":12345678}]But when we log the mapper deserialized one: This is our jackson libs in pom (maintained by jackson-bom v3.0.4): We already tried to add Any leads or advise on this finding is appreciated! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
|
First thing is that Lombok annotations need to be removed -- that is, we'd need de-lombokified version. Second would be to enable |
Beta Was this translation helpful? Give feedback.
First thing is that Lombok annotations need to be removed -- that is, we'd need de-lombokified version.
Second would be to enable
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIESwhich may show actual problems (default was changed to disabled in 3.0) but sounds like you already tries that.