I am making a remote call to external service A which would return the response as json and then using object mapper to de-serialize into MyResponse
object. After that in my current service, I need to attach this object and output to the UI.
One of the field in MyResponse
from service A is a boolean and I only want my UI response to include this field when the value is true. Note that I don't have access to modify my MyResponse
object as it was read-only. So I created a MixIn class also tried couple of ways but it didn't work..
public class MyResponse {
private String stringValue;
private int intValue;
// Expectation: only include this field when value true, and exclude it when value is false
private boolean booleanValue;
}
// @JsonIgnoreProperties(value = { "booleanValue" })
// @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private static class MixInMyResponse {
}
// this would be my rest service eventually send myResponse to UI
public MyResponse readFromRemote() throws IOException {
String jsonAsString =
"{\"stringValue\":\"a\",\"intValue\":1,\"booleanValue\":false}";
ObjectMapper mapper = new ObjectMapper();
// configure object mapper with mix in
mapper.getDeserializationConfig().addMixInAnnotations(MyResponse.class, MixInMyResponse.class);
MyResponse myResponse = mapper.readValue(jsonAsString, MyResponse.class);
// Expectation: writeValue needs only include booleanValue when value true, and exclude booleanValue when value is false
String writeValue = mapper.writeValueAsString(myResponse);
System.out.println(writeValue);
return myResponse;
}
@JsonIgnoreProperties(value = { "booleanValue" })
: this would do the trick when value is false, but also it doesn't include the field when value is true @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
: when value is false
, this would deserialized field booleanValue
as false, so my returned myResponse/writeValue
will still have this field to UI.Is there any additional suggestion on that?
Write your own Serializer
public class MyResponseSerializer extends JsonSerializer<MyResponse> {
@Override
public void serialize(MyResponse myResponse, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("stringValue", myResponse.getStringValue());
jsonGenerator.writeNumberField("intValue", myResponse.getIntValue());
if (myResponse.isBooleanValue()) {
jsonGenerator.writeBooleanField("booleanValue", myResponse.isBooleanValue());
}
jsonGenerator.writeEndObject();
}
}
Register it with the ObjectMapper
@Test
public void test3() throws IOException {
MyResponse response1 = new MyResponse("response1", 1, true);
MyResponse response2 = new MyResponse("response2", 1, false);
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(MyResponse.class, new MyResponseSerializer());
objectMapper.registerModule(module);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(response1));
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(response2));
}
See this tutorial
I edited the original answer when I saw you couldn't modify MyResponse to add an annotation.