Сериализация селективных переменных класса в Java - PullRequest
0 голосов
/ 13 апреля 2020

Мне нужно сериализовать некоторые поля в зависимости от условия.

Например, у меня есть следующий класс.

public class ClassExample
{
  private String id;
  private String type;
  private String string_1;
  private String string_2;
}

Итак, предполагая, что тип может получить два значения, 'type_1' или 'type_2', и что string_1 и string_2 всегда будут нулевыми (они будут изменены другим приложением).

Я хочу сериализовать это, используя Джексона, и я хочу:

1) Если это тип_1, строка_1 отображается в JSON, а строка_2 - нет.

2) Если это тип_2, строка_2 отображается в JSON, а строка_1 - нет.

Есть ли способ сделать это?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Насколько я понимаю, вы хотите сериализовать поля класса, которые соответствуют критериям. Есть несколько способов решить эту проблему, так как вам нужно решение без использования Custom serializer, вот решение: -

Решение основано на FilterProvider of Jackson.

Предложения: -

  1. Использовать Custom Serialiser, использовать упомянутое решение, если у вас очень жесткие ограничения
  2. Пожалуйста, введите Enum и используйте другую реализацию на основе действий типа соответственно .

Если вы можете уточнить ваш вариант использования, я могу порекомендовать лучшее решение.

Решение: -

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Getter
@Setter
@Slf4j
@AllArgsConstructor
@JsonFilter("myFilter")
public class ClassExample {
    private String id;
    private String type;
    private String string_1;
    private String string_2;
    private static final ObjectMapper om = new ObjectMapper();
    private static final PropertyFilter theFilter = new SimpleBeanPropertyFilter() {
        @Override
        public void serializeAsField(Object pojo, JsonGenerator jgen,
                                     SerializerProvider provider, PropertyWriter writer)
                throws Exception {
            if (include(writer)) {
                if (!(writer.getName().equals("string_1") || writer.getName().equals("string_2"))) {
                    writer.serializeAsField(pojo, jgen, provider);
                    return;
                }

                String type = ((ClassExample) pojo).getType();
                if ("type_1".equals(type) && (writer.getName().equals("string_1"))) {
                    writer.serializeAsField(pojo, jgen, provider);
                } else if ("type_2".equals(type) && (writer.getName().equals("string_2"))) {
                    writer.serializeAsField(pojo, jgen, provider);
                }

            } else if (!jgen.canOmitFields()) { // since 2.3
                writer.serializeAsOmittedField(pojo, jgen, provider);
            }
        }

        @Override
        protected boolean include(BeanPropertyWriter writer) {
            return true;
        }

        @Override
        protected boolean include(PropertyWriter writer) {
            return true;
        }
    };

    public String toString() {
        try {

            FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
            return om.writer(filters).writeValueAsString(this);
        } catch (Exception e) {
            log.error("error while serialisation", e);
            return "";
        }
    }

    public static void main(String[] args) {
        System.out.println(new ClassExample("123", "type_1", "1", "2"));
    }
}

Выход:

If type is type_1 then {"id":"123","type":"type_1","string_1":"1"}
If type if type_2 then {"id":"123","type":"type_2","string_2":"2"}

0 голосов
/ 13 апреля 2020

Обнуляемость поля в зависимости от другого, вероятно, является признаком того, что вы должны разделить ваши классы на 2. Вместо поля типа с двумя возможными значениями вы можете заменить это поле на 2 класса без какого-либо поля типа внутри. И поэтому нет необходимости в настраиваемом сериализаторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...