В настоящее время я использую jackson 2.1.4, и у меня возникают проблемы с игнорированием полей при преобразовании объекта в строку JSON.
Вот мой класс, который действует как объект, который нужно преобразовать:
public class JsonOperation {
public static class Request {
@JsonInclude(Include.NON_EMPTY)
String requestType;
Data data = new Data();
public static class Data {
@JsonInclude(Include.NON_EMPTY)
String username;
String email;
String password;
String birthday;
String coinsPackage;
String coins;
String transactionId;
boolean isLoggedIn;
}
}
public static class Response {
@JsonInclude(Include.NON_EMPTY)
String requestType = null;
Data data = new Data();
public static class Data {
@JsonInclude(Include.NON_EMPTY)
enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN };
enum Status { ok, error };
Status status;
ErrorCode errorCode;
String expiry;
int coins;
String email;
String birthday;
String pictureUrl;
ArrayList <Performer> performer;
}
}
}
И вот как я его конвертирую:
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
JsonOperation subscribe = new JsonOperation();
subscribe.request.requestType = "login";
subscribe.request.data.username = "Vincent";
subscribe.request.data.password = "test";
Writer strWriter = new StringWriter();
try {
mapper.writeValue(strWriter, subscribe.request);
} catch (JsonGenerationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("JSON", strWriter.toString())
Вот результат:
{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"}
Как я могу избежать этих нулевых значений? Я хочу взять необходимую информацию только для "подписки"!
Вот именно тот результат, который я ищу:
{"data":{"username":"Vincent","password":"test"},"requestType":"login"}
Я также попробовал @JsonInclude (Include.NON_NULL) и поместил все свои переменные в null, но это тоже не сработало! Спасибо за помощь ребята!
Ответы:
У вас есть аннотация не в том месте - она должна быть в классе, а не в поле. то есть:
@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case public static class Request { // ... }
Как отмечено в комментариях, в версиях ниже 2.x синтаксис этой аннотации:
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY
Другой вариант - настроить
ObjectMapper
напрямую, просто позвонивmapper.setSerializationInclusion(Include.NON_NULL);
(для записи, я думаю, что популярность этого ответа является признаком того, что эта аннотация должна применяться для каждого поля, @fasterxml)
источник
@JsonInclude(JsonSerialize.Inclusion.NON_NULL)
должно быть,@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
и это старый устаревший способ. поэтому вы должны@JsonInclude(Include.NON_NULL)
Вы также можете установить глобальную опцию:
источник
Также вы можете попробовать использовать
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
Если вы имеете дело с Джексоном с версией ниже 2+ (1.9.5), которую я тестировал, вы можете легко использовать эту аннотацию над классом. Не для указанных атрибутов, только для отмены класса.
источник
Вам нужно добавить
import com.fasterxml.jackson.annotation.JsonInclude;
Добавить
@JsonInclude(JsonInclude.Include.NON_NULL)
поверх POJO
Если у вас есть вложенный POJO, тогда
@JsonInclude(JsonInclude.Include.NON_NULL)
нужно добавить все значения.
ПРИМЕЧАНИЕ: JAXRS (Джерси) автоматически обрабатывает этот сценарий 2.6 и выше.
источник
Для jackson 2.x
@JsonInclude(JsonInclude.Include.NON_NULL)
прямо перед полем.
источник
Недавно у меня была аналогичная проблема с версией 2.6.6.
@JsonInclude(JsonInclude.Include.NON_NULL)
Использование вышеуказанной аннотации на уровне поля или класса не работало должным образом. POJO был изменен там, где я применял аннотацию. Когда я изменил поведение POJO, сделав его неизменным, аннотации сработали.
Я не уверен, что до новой версии или предыдущих версий этой библиотеки было подобное поведение, но для 2.6.6, безусловно, вам понадобится Immutable POJO, чтобы аннотация работала.
Вышеупомянутый вариант, упомянутый в различных ответах о настройке включения сериализации в ObjectMapper непосредственно на глобальном уровне, также работает, но я предпочитаю контролировать его на уровне класса или поля.
Поэтому, если вы хотите, чтобы все пустые поля игнорировались во время сериализации JSON, используйте аннотацию на уровне класса, но если вы хотите, чтобы в классе игнорировалось только несколько полей, используйте ее для этих конкретных полей. Таким образом, он более читабелен и прост в обслуживании, если вы хотите изменить поведение для определенного ответа.
источник
Или вы можете использовать GSON [ https://code.google.com/p/google-gson/ ], где эти пустые поля будут автоматически удалены.
SampleDTO.java
public class SampleDTO { String username; String email; String password; String birthday; String coinsPackage; String coins; String transactionId; boolean isLoggedIn; // getters/setters }
Test.java
import com.google.gson.Gson; public class Test { public static void main(String[] args) { SampleDTO objSampleDTO = new SampleDTO(); Gson objGson = new Gson(); System.out.println(objGson.toJson(objSampleDTO)); } }
ВЫХОД:
{"isLoggedIn":false}
Я использовал gson-2.2.4
источник
Приведенный ниже код может помочь, если вы хотите исключить логический тип из сериализации:
@JsonInclude(JsonInclude.Include.NON_ABSENT)
источник