Пользовательская аннотация Джексона для пользовательской сериализации значения NULL - PullRequest
0 голосов
/ 07 июня 2018

Согласно этому ответу: https://stackoverflow.com/a/43342675/5810648

Я написал такой сериализатор:

public class CustomSerializer extends StdSerializer<Double> implements ContextualSerializer {

    private final NAifNull annotation;

    public CustomSerializer() {
        super(Double.class);
        this.annotation = null;
    }

    public CustomSerializer(NAifNull annotation) {
        super(Double.class);
        this.annotation = annotation;
    }

    @Override
    public void serialize(Double value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (annotation != null && value == null) {
            gen.writeString("N/A");
        } else {
            gen.writeNumber(value);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
        NAifNull annotation = property.getAnnotation(NAifNull.class);
        return new CustomSerializer(annotation);
    }
}

Ведьма должна написать строку «N / A», если аннотация присутствует и поле null.Но метод serialize вызывается только для ненулевых полей.

Также я пытался позвонить setNullValueSerializer:

@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
    NAifNull annotation = property.getAnnotation(NAifNull.class);
    prov.setNullValueSerializer(new CustomNullSerializer(annotation));
    return new CustomSerializer(annotation);
}

С такой реализацией:

private static class CustomNullSerializer extends JsonSerializer<Object> {
    private final NAifNull annotation;

    public CustomNullSerializer(NAifNull annotation) {
        this.annotation = annotation;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (annotation != null) {
            gen.writeString("N/A");
        } else {
            gen.writeNull();
        }
    }
}

Но без результата.

Какобрабатывать пустые поля таким образом?

Обновление

Согласно обсуждению: https://github.com/FasterXML/jackson-databind/issues/2057

prov.setNullValueSerializer(new CustomNullSerializer(annotation));

Не вызывается изCreateContextual метод.

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Используйте BeanSerializerModifier, чтобы настроить пустой сериализатор для конкретного свойства :

public class CustomBeanSerializerModifier extends BeanSerializerModifier {

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, 
           BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {

        for (BeanPropertyWriter beanProperty : beanProperties) {
            if (beanProperty.getAnnotation(NAifNull.class) != null) {
                beanProperty.assignNullSerializer(new CustomNullSerializer());
            }
        }

        return beanProperties;
    }
}

Где @NAifNull и CustomNullSerializer определены какследует:

public class CustomNullSerializer extends JsonSerializer<Object> {

    @Override
    public void serialize(Object value, JsonGenerator jgen, 
           SerializerProvider provider) throws IOException {
        jgen.writeString("N/A");
    }
}
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@interface NAifNull {

}

Затем используйте его следующим образом:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {

    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.addBeanSerializerModifier(new CustomBeanSerializerModifier());
    }
});
0 голосов
/ 07 июня 2018

Если я вас правильно понял, вы хотите написать «N / A» в сгенерированный JSON, если значение равно нулю.

Документы Джексона утверждают, что значение не может быть нулевым.Это потому, что параметром типа является объект класса, который создается автоматически JVM .

В соответствии с этой статьей , я думаю, вы могли бы обрабатывать пустые поля с чем-то вроде

public class CustomNullSerializer extends StdSerializer<Object> {

   public CustomNullSerializer() {
        this(null);
   }

   public CustomNullSerializer(Class<Object> t) {
        super(t);
   }

   @Override
   public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString("N/A");
   }
}

А затем используйте его с

prov.setNullValueSerializer(new CustomNullSerializer());

Хотя я сам не пробовал, но надеюсь, что это поможет.

ОБНОВЛЕНИЕ

Хорошо, теперь у меня было время попробовать это сам.Я получил это работает с

ObjectMapper mapper...
mapper.getSerializerProvider().setNullValueSerializer(new CustomNullSerializer());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...