Я пытаюсь изучить Gson, и я борюсь с полевым исключением. Вот мои занятия
public class Student {
private Long id;
private String firstName = "Philip";
private String middleName = "J.";
private String initials = "P.F";
private String lastName = "Fry";
private Country country;
private Country countryOfBirth;
}
public class Country {
private Long id;
private String name;
private Object other;
}
Я могу использовать GsonBuilder и добавить ExclusionStrategy для имени поля, например firstName
или, country
но мне не удается исключить свойства некоторых полей, таких как country.name
.
Используя метод public boolean shouldSkipField(FieldAttributes fa)
, FieldAttributes не содержит достаточно информации, чтобы сопоставить поле с фильтром, как country.name
.
PS: я хочу избежать аннотаций, так как я хочу улучшить это и использовать RegEx для фильтрации полей.
Изменить : я пытаюсь увидеть, возможно ли эмулировать поведение JSON-плагина Struts2
используя Gson
<interceptor-ref name="json">
<param name="enableSMD">true</param>
<param name="excludeProperties">
login.password,
studentList.*\.sin
</param>
</interceptor-ref>
Изменить: я вновь открыл вопрос со следующим дополнением:
Я добавил второе поле того же типа, чтобы прояснить эту проблему. В основном я хочу исключить, country.name
но нет countrOfBirth.name
. Я также не хочу исключать страну как тип. Таким образом, типы одинаковы, это фактическое место в графе объектов, которое я хочу точно определить и исключить.
источник
JsonSerializer
для некоторого типа -Country
в вашем случае - для которого затем применяется,ExclusionStrategy
который решает, какие поля для сериализации.Ответы:
Любые поля, которые вы не хотите сериализовать, следует использовать модификатор «transient», и это также относится к сериализаторам json (по крайней мере, к некоторым, которые я использовал, включая gson).
Если вы не хотите, чтобы имя отображалось в сериализованном json, дайте ему временное ключевое слово, например:
Более подробная информация в документации Gson
источник
transient
вместо этого@Expose
заключается в том, что вам все еще нужно смоделировать POJO на своем клиенте со всеми полями, которые могут быть введены. В случае с внутренним API, который может быть общим для проектов, это может быть проблематично в случае добавлены дополнительные поля. По сути, это белый список против черного списка полей.Нишант предоставил хорошее решение, но есть более простой способ. Просто пометьте нужные поля аннотацией @Expose, например:
Оставьте все поля, которые вы не хотите сериализовать. Затем просто создайте свой объект Gson следующим образом:
источник
Итак, вы хотите исключить
firstName
иcountry.name
. Вот как выExclusionStrategy
должны выглядетьЕсли вы внимательно посмотрите, это возвращает
true
дляStudent.firstName
иCountry.name
, что вы хотите исключить.Вы должны применить это
ExclusionStrategy
так,Это возвращает:
Я предполагаю, что объект страны инициализируется
id = 91L
в классе ученика.Вы можете стать модным. Например, вы не хотите сериализовать любое поле, содержащее строку «name» в своем имени. Сделай это:
Это вернет:
РЕДАКТИРОВАТЬ: Добавлена дополнительная информация по запросу.
Это
ExclusionStrategy
сработает, но вам нужно передать «Полное имя поля». См. ниже:Вот как мы можем использовать это в общем.
Возвращает:
источник
country.name
и исключать поле толькоname
при сериализации поляcountry
. Он должен быть достаточно универсальным, чтобы применяться к каждому классу, у которого есть свойство с именем страна класса Country. Я не хочу создавать стратегию исключения для каждого классаПрочитав все доступные ответы, я обнаружил, что наиболее гибким в моем случае было использование пользовательских
@Exclude
аннотаций. Итак, я реализовал простую стратегию для этого (я не хотел отмечать все поля, используя,@Expose
и я не хотел использовать,transient
что противоречило вSerializable
сериализации приложения ):Аннотация:
Стратегия:
Применение:
источник
addSerializationExclusionStrategy
илиaddDeserializationExclusionStrategy
вместоsetExclusionStrategies
f.getAnnotation(Exclude.class) != null
наf.getAnnotation(Exclude.class) == null
transient
из-за потребностей других библиотек. Спасибо!Я столкнулся с этой проблемой, в которой у меня было небольшое количество полей, которые я хотел исключить только из сериализации, поэтому я разработал довольно простое решение, которое использует
@Expose
аннотацию Gson с пользовательскими стратегиями исключения.Единственный встроенный способ
@Expose
- настройкаGsonBuilder.excludeFieldsWithoutExposeAnnotation()
, но, как видно из названия, поля без явного@Expose
игнорируются. Поскольку у меня было только несколько полей, которые я хотел исключить, я обнаружил, что перспектива добавления аннотации к каждому полю очень громоздка.Я фактически хотел обратное, в котором все было включено, если я явно не использовал,
@Expose
чтобы исключить его. Для этого я использовал следующие стратегии исключения:Теперь я могу легко исключить несколько полей с аннотациями
@Expose(serialize = false)
или@Expose(deserialize = false)
(заметьте, что значение по умолчанию для обоих@Expose
атрибутов равноtrue
). Вы можете, конечно, использовать@Expose(serialize = false, deserialize = false)
, но это более кратко достигается путем объявления поляtransient
вместо этого (что все еще вступает в силу с этими пользовательскими стратегиями исключения).источник
Вы можете исследовать дерево JSON с помощью GSON.
Попробуйте что-то вроде этого:
Вы также можете добавить некоторые свойства:
Протестировано с помощью gson 2.2.4.
источник
Я придумал фабрику классов для поддержки этой функциональности. Передайте любую комбинацию полей или классов, которые вы хотите исключить.
Чтобы использовать, создайте два списка (каждый необязательно), и создайте свой объект GSON:
источник
Я решил эту проблему с помощью пользовательских аннотаций. Это мой класс аннотации "SkipSerialisation":
а это мой GsonBuilder:
Пример :
источник
@Retention(RetentionPolicy.RUNTIME)
к своей аннотации.Или можете сказать, что поля не будут выставлены с:
в вашем классе по атрибуту:
источник
excludeFieldsWithModifiers()
это.Я использовал эту стратегию: я исключил все поля, которые не помечены аннотацией @SerializedName , то есть:
Возвращается
источник
Другой подход (особенно полезный, если вам необходимо принять решение об исключении поля во время выполнения), состоит в регистрации TypeAdapter в вашем экземпляре gson. Пример ниже:
В приведенном ниже случае сервер ожидает одно из двух значений, но, поскольку они оба являются целыми числами, gson будет сериализовать их оба. Моя цель состояла в том, чтобы опустить любое значение, которое равно нулю (или меньше) в json, который публикуется на сервере.
источник
@Transient
Очевидно, что аннотация Котлина тоже помогает.Вывод:
источник
Я работаю просто, поставив
@Expose
аннотацию, вот моя версия, которую я используюВ
Model
классе:В
Adapter
классе:источник
У меня есть версия Kotlin
и как вы можете добавить это в Retrofit GSONConverterFactory:
источник
Это то, что я всегда использую:
Поведение по умолчанию, реализованное в Gson, заключается в том, что нулевые поля объекта игнорируются.
Означает, что объект Gson не сериализует поля с нулевыми значениями в JSON. Если поле в объекте Java является нулевым, Gson исключает его.
Вы можете использовать эту функцию, чтобы преобразовать какой-либо объект в ноль или установить его самостоятельно
источник