Reputation: 55
Say I have classes Foo
public class Foo {
private Bar bar;
}
and Bar
public class Bar {
private String fizz;
private String bang;
}
EDIT: For clarification I do not own Foo
and Bar
and cannot alter these classes.
If I want to serialize an empty object of type Foo, it's member, which is of type Bar, will be returned as null.
String json = objectMapper.writeValueAsString(new Foo()); // "{"bar" : null}"
Is there any way I can get the object mapper to serialize an empty Bar object without having to instantiate a new instance of Bar and then adding it to a new instance of Foo?
String json = objectMapper.writeValueAsString(new Foo()) // "{bar": {"fizz" : null, "bang" : null } }"
Upvotes: 4
Views: 18403
Reputation: 331
If you don't want to write your own serializer you can use this approach of declaring type of field as ObjectNode:
private ObjectNode data;
You can set/initialize it like this:
data = new ObjectNode(JsonNodeFactory.instance)
Upvotes: 2
Reputation: 50
It's a bit unrelated to this, but if you define members as private on data class in Kotlin, then, Jackson serializer will produce empty json such as {}
.
Upvotes: 0
Reputation: 2568
I was also required to produce such a structure for legacy client compatibility, here is my solution (depends on Spring Boot since uses @JsonComponent annotation)
Create "special object" that will be treated as empty
public class EmptyObject {
}
Create property in your model
@JsonProperty("data")
private EmptyObject data = new EmptyObject();
public EmptyObject getData() {
return data;
}
Create serializer that will process empty object above
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.sevensenders.datahub.api.service.response.model.EmptyObject;
import org.springframework.boot.jackson.JsonComponent;
import java.io.IOException;
@JsonComponent
public class EmptyObjectSerializer extends StdSerializer<EmptyObject> {
public EmptyObjectSerializer() {
this(null);
}
public EmptyObjectSerializer(Class<EmptyObject> t) {
super(t);
}
@Override
public void serialize(EmptyObject value, JsonGenerator gen, SerializerProvider provider) throws IOException {
// to maintain AF compatible format it is required to write {} instead of null
gen.writeStartObject();
gen.writeEndObject();
}
}
Output:
{
...
"data": {}
}
Upvotes: 9
Reputation: 935
You could create a custom serializer for serializing Foo objects. Then in your custom FooSerializer implementation, you could check for a null bar value and serialize it as a default Bar instance. See https://spin.atomicobject.com/2016/07/01/custom-serializer-jackson/ or http://www.baeldung.com/jackson-custom-serialization for some examples of how to create custom serializers.
Upvotes: 1
Reputation:
No. I don't see any way doing this. If you don't initialize your Bar
, it'll be null
inside the JSON
.
Since you can't alter these classes, you can just check if the Bar
inside the Foo
is null
and if it is, just initialize it and you'll get what you want.
Bar bar = foo.getBar();
if (bar == null) {
foo.setBar(new Bar());
}
String json = objectMapper.writeValueAsString(foo);
The json
will be the following:
{
"bar" : {
"fizz" : null,
"bang" : null
}
}
Hope this helps.
Upvotes: -2