Jackson ObjectMapper - 从远程响应反序列化后,如何在值为 false 时排除字段?
Jackson ObjectMapper - How to exclude field when value is false after de-serialized from remote response?
我正在远程调用外部服务 A,它将 return 响应作为 json,然后使用对象映射器反序列化为 MyResponse
对象。在那之后,在我当前的服务中,我需要附加这个对象并输出到 UI.
来自服务 A 的 MyResponse
中的一个字段是布尔值,我只希望我的 UI 响应在值为真时包含此字段。 请注意,我无权修改我的 MyResponse
对象,因为它是只读的。所以我创建了一个 MixIn class 也尝试了几种方法但是没有用..
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" })
:当值为 false 时这会起作用,但当值为 true 时它也不包括该字段
- 使用
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
:当值是 false
时,这会将字段 booleanValue
反序列化为 false,所以我的 returned myResponse/writeValue
仍然会有这个字段到 UI.
对此还有什么建议吗?
编写您自己的序列化程序
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();
}
}
用 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));
}
看到这个tutorial
当我看到您无法修改 MyResponse 以添加注释时,我编辑了原始答案。
你当然可以这样做。
首先,您的 booleanValue
字段应该是盒装类型 Boolean
而不是预设类型 boolean
。因为原始类型 boolean
默认值为 false.
您可以为 booleanValue
创建一个 setter 方法并用 @JsonProperty("booleanValue")
注释它,如下所示。
public class MyResponse {
private String stringValue;
private int intValue;
private Boolean booleanValue;
@JsonProperty("booleanValue")
public void anyNameYouWant(Boolean b) {
if(b) this.booleanValue = true;
}
// getters and setters
}
终于可以进行以下操作了,
String s = "{\"stringValue\":\"a\",\"intValue\":1,\"booleanValue\":false}";
ObjectMapper om = new ObjectMapper();
om.readValue(s, MyResponse.class);
我正在远程调用外部服务 A,它将 return 响应作为 json,然后使用对象映射器反序列化为 MyResponse
对象。在那之后,在我当前的服务中,我需要附加这个对象并输出到 UI.
来自服务 A 的 MyResponse
中的一个字段是布尔值,我只希望我的 UI 响应在值为真时包含此字段。 请注意,我无权修改我的 MyResponse
对象,因为它是只读的。所以我创建了一个 MixIn class 也尝试了几种方法但是没有用..
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" })
:当值为 false 时这会起作用,但当值为 true 时它也不包括该字段 - 使用
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
:当值是false
时,这会将字段booleanValue
反序列化为 false,所以我的 returnedmyResponse/writeValue
仍然会有这个字段到 UI.
对此还有什么建议吗?
编写您自己的序列化程序
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();
}
}
用 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));
}
看到这个tutorial
当我看到您无法修改 MyResponse 以添加注释时,我编辑了原始答案。
你当然可以这样做。
首先,您的 booleanValue
字段应该是盒装类型 Boolean
而不是预设类型 boolean
。因为原始类型 boolean
默认值为 false.
您可以为 booleanValue
创建一个 setter 方法并用 @JsonProperty("booleanValue")
注释它,如下所示。
public class MyResponse {
private String stringValue;
private int intValue;
private Boolean booleanValue;
@JsonProperty("booleanValue")
public void anyNameYouWant(Boolean b) {
if(b) this.booleanValue = true;
}
// getters and setters
}
终于可以进行以下操作了,
String s = "{\"stringValue\":\"a\",\"intValue\":1,\"booleanValue\":false}";
ObjectMapper om = new ObjectMapper();
om.readValue(s, MyResponse.class);