Background
- I want to clone DTOs that store values from a request in Spring Boot.
- Sometimes it has a non-serializable field (i.e.
MultipartFile
), so I can't use the strategy to useObjectOutputStream
/ObjectInputStream
like https://stackoverflow.com/a/64066/3902663 .
- Sometimes it has a non-serializable field (i.e.
- I don't have control over these DTOs, so I can't add a
transient
modifier to ignore these fields.
What I tried
I tried to write a method with Jackson's ObjectMapper
. You can use @JsonIgnoreType
and ObjectMapper#addMixIn()
to ignore non-serializable fields according to their class without changing the definition of DTOs.
private Object makeClone(Object obj) {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(MultipartFile.class, JacksonMixInForIgnoreType.class);
try {
return mapper.readValue(mapper.writeValueAsString(obj), obj.getClass());
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@JsonIgnoreType
class JacksonMixInForIgnoreType {}
Problem
You can't ignore the field like MultipartFile[] fileArray;
with this strategy. When you have an array of MultipartFile
in a DTO to upload multiple files, the code above throws an exception like this:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.example.uploadingfiles.DeepCopyDto["fileArray"]->org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile[0]->org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile["inputStream"]->java.io.FileInputStream["fd"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.13.1.jar:2.13.1]
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300) ~[jackson-databind-2.13.1.jar:2.13.1]
...
Question
Is there any way to tell Jackson to ignore a property that is an array/collection of a specific type?