Пользовательский сериализатор Джексона с подавлением нулевых значений
У меня есть настраиваемый сериализатор для обработки String с пустыми значениями как null, а также для обрезки конечных пробелов. Follwoing - это код того же. -
public class StringSerializer extends JsonSerializer<String> {
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
String finalValue = null;
if (value != null) {
finalValue = value.trim();
if (finalValue.isEmpty()) {
finalValue = null;
}
}
gen.writeObject(finalValue);
}
}
В основном определении bean-компонента определение атрибута выглядит следующим образом:
public class SampleBean {
private Long id;
@JsonSerialize(using = StringSerializer.class)
@JsonInclude(Include.NON_NULL)
private String attribute1;
@JsonSerialize(using = StringSerializer.class)
@JsonInclude(Include.NON_NULL)
private String attribute2;
//Getters and setters
}
В случаях, когда срабатывает пользовательский сериализатор, ненулевые значения не игнорируются.
Например:
SampleBean bean = new SampleBean();
bean.setId(1L);
bean.setAttribtute1("abc");
bean.setAttribtute2(" ");
new ObjectMapper().writeValueAsString(bean);
Вывод writeValueAsString: {"id": 1, "attribute1": "abc", "attribute2": null}
Ожидаемый результат, поскольку у меня есть @JsonInclude(Include.NON_NULL) в атрибуте 2, как показано ниже. {"id": 1, "attribute1": "abc"}
Есть ли способ добиться этого?
4 ответа
У меня была точно такая же проблема, как и у вас. В итоге я создал настраиваемый фильтр и использовал его вместе с настраиваемым сериализатором.
Обратите внимание, что пример в ссылке https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html неверен. В методе equals() вы должны вернуть true, если вы НЕ хотите включать поле, и вернуть false, если хотите, чтобы поле было сериализованным выводом. Это противоположно примеру.
Пример кода:
/**
* Custom Jackson Filter used for @JsonInclude. When the keywords string is empty don't include keywords in the
* JSON serialization.
*/
public class KeywordsIncludeFilter {
@Override
public boolean equals(Object obj) {
if(obj == null) return true;
if(obj instanceof String && "".equals((String) obj)) return true;
return false;
}
}
Попробуйте добавить в свой
StringSerializer
:
@Override
public boolean isEmpty(SerializerProvider provider, String value) {
if (value != null) {
String finalValue = value.trim();
if (finalValue.isEmpty()) {
return true;
}
}
return false;
}
Затем добавьте «непустую» аннотацию к рассматриваемому полю, например:
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String attribute2;
Это устанавливает подавляемое значение как «непустое», которое затем можно определить с помощью
isEmpty()
переопределить.
Попробуйте NON_EMPTY, который должен заботиться о пустой и нулевой строке.
@JsonSerialize(using =
StringSerializer.class)
@JsonInclude(Include.NON_EMPTY)
Если это не соответствует вашим требованиям, посмотрите здесь, чтобы создать настраиваемый фильтр, а затем используйте его в valueFilter.
https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html
Вы устанавливаете свое значение в пробел вместо нуля.
bean.setAttribtute2(" ");
Попробуйте с нулем.
bean.setAttribtute2(null);