Поле Gson Serialize, если оно не пустое или не пустое

У меня есть требование, когда мне нужно преобразовать java-объект в json.

Я использую Gson для этого, но мне нужен конвертер для сериализации непустых или не пустых значений.

Например:

//my java object looks like class TestObject{ String test1; String test2; OtherObject otherObject = new OtherObject(); } 

теперь мой экземпляр Gson для преобразования этого объекта в json выглядит

 Gson gson = new Gson(); TestObject obj = new TestObject(); obj.test1 = "test1"; obj.test2 = ""; String jsonStr = gson.toJson(obj); println jsonStr; 

В приведенной выше печати результат

 {"test1":"test1", "test2":"", "otherObject":{}} 

Здесь я просто хотел, чтобы результат был

 {"test1":"test1"} 

Поскольку test2 пуст, а otherObject пуст, я не хочу, чтобы они были сериализованы для json-данных.

Кстати, я использую Groovy / Grails, поэтому, если для этого есть какой-нибудь плагин, это было бы хорошо, если бы не было никаких предложений по настройке classа сериализации gson.

Создайте свой собственный TypeAdapter

 public class MyTypeAdapter extends TypeAdapter() { @Override public void write(JsonWriter out, TestObject value) throws IOException { out.beginObject(); if (!Strings.isNullOrEmpty(value.test1)) { out.name("test1"); out.value(value.test1); } if (!Strings.isNullOrEmpty(value.test2)) { out.name("test2"); out.value(value.test1); } /* similar check for otherObject */ out.endObject(); } @Override public TestObject read(JsonReader in) throws IOException { // do something similar, but the other way around } } 

Затем вы можете зарегистрировать его с помощью Gson .

 Gson gson = new GsonBuilder().registerTypeAdapter(TestObject.class, new MyTypeAdapter()).create(); TestObject obj = new TestObject(); obj.test1 = "test1"; obj.test2 = ""; System.out.println(gson.toJson(obj)); 

производит

  {"test1":"test1"} 

Класс GsonBuilder имеет множество методов для создания собственных страtagsй сериализации / десериализации, адаптеров типа регистров и установки других параметров.

Strings – это class Guava. Вы можете сделать свою собственную проверку, если вам не нужна эта зависимость.

То, что мне лично не нравится в TypeAdapter с использованием ответа, – это тот факт, что вам нужно описать все поля вашего всего classа, которые могли бы позволить сказать 50 полей (что означает 50, if блоки в TypeAdapter ).
Мое решение основано на Reflection и факт, что Gson не будет сериализовать поля нулевых значений по умолчанию.
У меня есть специальный class, который содержит данные для API для создания документа под названием DocumentModel, который имеет около 50 полей, и мне не нравится отправлять поля String со значениями «» или пустые массивы на сервер. Поэтому я создал специальный метод, который возвращает мне копию моего объекта со всеми пустыми полями. Примечание. По умолчанию все массивы в моем экземпляре DocumentModel инициализируются как пустые (нулевые длины) массивы и, следовательно, они никогда не являются нулевыми, вы должны, вероятно, проверить свои массивы на нуль, прежде чем проверять их длину.

 public DocumentModel getSerializableCopy() { Field fields[] = new Field[]{}; try { // returns the array of Field objects representing the public fields fields = DocumentModel.class.getDeclaredFields(); } catch (Exception e) { e.printStackTrace(); } DocumentModel copy = new DocumentModel(); Object value; for (Field field : fields) { try { value = field.get(this); if (value instanceof String && TextUtils.isEmpty((String) value)) { field.set(copy, null); // note: here array is not being checked for null! else if (value instanceof Object[] && ((Object[]) value).length == 0) { field.set(copy, null); } else field.set(copy, value); } catch (IllegalAccessException e) { e.printStackTrace(); } } return copy; } 

Используя этот метод, мне все равно, добавлены ли некоторые поля после того, как этот метод был написан или что-то еще. Единственная проблема – проверка полей пользовательского типа, которые не являются String или массивами, но это зависит от конкретного classа и должно быть дополнительно закодировано в блоках if / else.

Мне кажется, что проблема не в том, что с gson. Gson правильно отслеживает разницу между нулевой и пустой строкой. Вы уверены, что хотите стереть это различие? Вы уверены, что все classы, использующие TestObject, не заботятся?

Что вы могли бы сделать, если вам не нужна разница, – это изменить пустые строки до нуля в TestObject перед его сериализацией. Или лучше, сделайте сеттеры в TestObject таким образом, чтобы пустая строка была равна нулю; таким образом вы строго определяете внутри classа, что пустая строка совпадает с нулевой. Вы должны будете убедиться, что значения не могут быть установлены за пределами сеттеров.

  • Использование StringWriter для сериализации XML
  • Можно ли сериализовать и десериализовать class в C ++?
  • Обратный (проанализировать вывод) массива Array.toString (int )
  • FileMode.Open и FileMode.OpenOrCreate разница, когда файл существует? c # ошибка?
  • Можете ли вы указать формат для XmlSerialization datetime?
  • Сериализация списков classов для XML
  • В чем разница между Serializable и Externalizable в Java?
  • Сериализация / десериализация с streamом памяти
  • Серийный список JSON <KeyValuePair >
  • Как писать и читать java-сериализованные объекты в файл
  • Как преобразовать двоичные данные в строки и обратно в Java?
  • Давайте будем гением компьютера.