Jackson Serialization issue with CommonsMultipartFile
Solution 1
It's not clear how Jackson is being used, as no code or description was provided in the original question.
By default, Jackson skips all transient fields during serialization.
import java.io.Serializable;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.ObjectMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
System.out.println(mapper.writeValueAsString(new Placement()));
// output: {"placementId":42,"type":"OK","placement":"left"}
// transient fields are skipped by default
}
}
class Placement implements Serializable
{
private static final long serialVersionUID = 1L;
private long placementId = 42;
private String type = "OK";
private String placement = "left";
private transient CommonsMultipartFile fileData = new CommonsMultipartFile();
}
class CommonsMultipartFile
{
private String name = "Fred";
}
If there is a getter for the transient field, however, then by default Jackson includes it during serialization.
import java.io.Serializable;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.ObjectMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
System.out.println(mapper.writeValueAsString(new Placement()));
// output: {"placementId":42,"type":"OK","placement":"left","fileData":{"name":"Fred"}}
// transient fields with getters are not skipped by default
}
}
class Placement implements Serializable
{
private static final long serialVersionUID = 1L;
private long placementId = 42;
private String type = "OK";
private String placement = "left";
private transient CommonsMultipartFile fileData = new CommonsMultipartFile();
public CommonsMultipartFile getFileData() {return fileData;}
}
class CommonsMultipartFile
{
private String name = "Fred";
}
One configuration option to skip the getter is to just apply the @JsonIgnore annotation.
import java.io.Serializable;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.ObjectMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
System.out.println(mapper.writeValueAsString(new Placement()));
// output: {"placementId":42,"type":"OK","placement":"left"}
// getters marked with @JsonIgnore are ignored
}
}
class Placement implements Serializable
{
private static final long serialVersionUID = 1L;
private long placementId = 42;
private String type = "OK";
private String placement = "left";
private transient CommonsMultipartFile fileData = new CommonsMultipartFile();
@JsonIgnore
public CommonsMultipartFile getFileData() {return fileData;}
}
class CommonsMultipartFile
{
private String name = "Fred";
}
If it's not possible or desirable to edit the original class definition to add the @JsonIgnore annotation, a Mix-In can be used.
import java.io.Serializable;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.ObjectMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
mapper.getSerializationConfig().addMixInAnnotations(Placement.class, SkipFileDataMixIn.class);
System.out.println(mapper.writeValueAsString(new Placement()));
// output: {"placementId":42,"type":"OK","placement":"left"}
// getters marked with @JsonIgnore are ignored
}
}
abstract class SkipFileDataMixIn
{
@JsonIgnore
public abstract CommonsMultipartFile getFileData();
}
class Placement implements Serializable
{
private static final long serialVersionUID = 1L;
private long placementId = 42;
private String type = "OK";
private String placement = "left";
private transient CommonsMultipartFile fileData = new CommonsMultipartFile();
public CommonsMultipartFile getFileData() {return fileData;}
}
class CommonsMultipartFile
{
private String name = "Fred";
}
Another approach is to mark the type to be skipped with @JsonIgnoreType
.
import java.io.Serializable;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonIgnoreType;
import org.codehaus.jackson.map.ObjectMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
System.out.println(mapper.writeValueAsString(new Placement()));
// output: {"placementId":42,"type":"OK","placement":"left"}
// Types marked with @JsonIgnoreType are ignored during serialization.
}
}
class Placement implements Serializable
{
private static final long serialVersionUID = 1L;
private long placementId = 42;
private String type = "OK";
private String placement = "left";
private transient CommonsMultipartFile fileData = new CommonsMultipartFile();
public CommonsMultipartFile getFileData() {return fileData;}
}
@JsonIgnoreType
class CommonsMultipartFile
{
private String name = "Fred";
}
Solution 2
If you do not want to serialize the multipartfile then add the annotation @JsonIgnore
to the field.
@JsonIgnore
private CommonsMultipartFile fileData;
You can read more abot jackson annotations here.
Comments
-
Ankush almost 2 years
I have a bean with CommonsMultipartFile type field like so:
public class Placement implements Serializable { private static final long serialVersionUID = 1L; private long placementId; private String type; private String placement; private transient CommonsMultipartFile fileData;
I have marked CommonsMultipartFile field as transient and trying to serialize to json using jackson library. But getting following error:
org.codehaus.jackson.map.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: nextag.travel.dashboard.model.Placement["fileData"]->org.springframework.web.multipart.commons.CommonsMultipartFile["inputStream"])
Any help/ suggestions would be highly appreciated.