Сериализация с Джексоном (JSON) - получение "не найден сериализатор"?
Я получаю исключение при попытке сериализовать очень простой объект с помощью Джексона. Ошибка:
org.codehaus.Джексон.карта.JsonMappingException: сериализатор не найден
класс MyPackage.TestA и никаких свойств
обнаружен для создания BeanSerializer (чтобы избежать исключения, отключите
SerializationConfig.Особенность.FAIL_ON_EMPTY_BEANS))
Ниже приведен простой класс и код для сериализации.
может кто-нибудь сказать мне, почему я получаю это ошибка?
public class TestA {
String SomeString = "asd";
}
TestA testA = new TestA();
ObjectMapper om = new ObjectMapper();
try {
String testAString = om.writeValueAsString(testA); // error here!
TestA newTestA = om.readValue(testAString, TestA.class);
} 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();
}
14 ответов:
как уже описано, конфигурация по умолчанию
ObjectMapperэкземпляр предназначен только для доступа к свойствам, которые являются общедоступными полями или имеют общедоступные геттеры/сеттеры. Альтернативой изменению определения класса, чтобы сделать поле общедоступным или предоставить общедоступный геттер / сеттер, является указание (для базовогоVisibilityChecker) другое правило видимости свойств. Джексон 1.9 обеспечиваетObjectMapper.setVisibility()удобный метод для этого. Для примера в исходном вопросе я бы, вероятно, настроил это какmyObjectMapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);для получения дополнительной информации и сведений о соответствующих параметрах конфигурации, я рекомендую просмотреть JavaDocs на
ObjectMapper.setVisibility().
для Джексона сериализовать этот класс,
SomeStringполе должно быть либоpublic(прямо сейчас это изоляция уровня пакета) или вам нужно определить методы getter и setter для него.
как было предложено в исключении, я добавил следующую строку, чтобы избежать сбоя на пустых бобах:
Для Джексона 1.9
myObjectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);Для Джексона 2.X
myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);Вы можете найти простой пример Джексон отключить fail_on_empty_beans
эта ошибка также возникает, если вы забыли добавить .build () метод на ваш статус возврата.
return Response.status(Status.OK); // fails return Response.status(Status.OK).build(); // worksЯ получил следующую ошибку без метода build ():
org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.sun.jersey.core.spi.factory.ResponseBuilderImpl
Если вы можете редактировать класс, содержащий этот объект, я обычно просто добавляю аннотацию
import com.fasterxml.jackson.annotation.JsonIgnore; @JsonIgnore NonSerializeableClass obj;
У меня была такая же проблема для дочернего класса, где у меня был контроль, Object mapper был в общем модуле и был недоступен. Я решил это, добавив эту аннотацию для моего дочернего класса, объект которого должен был быть сериализован.
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
для приложений Oracle Java добавьте это после
ObjectMapperсоздание экземпляра:mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
проблема может быть в том, что вы объявили переменную как
private. Если вы измените его наpublic, он работает.лучший вариант-использовать для этого методы getter и setter.
это решит проблему!
У меня была аналогичная проблема с ленивой загрузкой через прокси-объект hibernate. Обошел его, аннотируя класс, имеющий ленивые загруженные частные свойства:
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
вот три варианта:
- данные / класс, к которому был получен доступ, должны быть
public- , если не
publicдобавьте геттеры и сеттеры- или добавить
@JsonIgnore("context")
хотя я добавил геттеры и сеттеры, я получал ту же ошибку. Позже я нашел ошибку, то есть по совету сонара я cgahnged геттеры и сеттеры как защищенные, что вызвало проблему. Как только я исправил, что он работал как exppected.
Я нашел по крайней мере три способа сделать это:
- добавить
public gettersна вашей сущности, которую вы пытаетесь сериализовать;- добавьте аннотацию в верхней части объекта, если вы не хотите
public getters. Это изменит значение по умолчанию для Джексона сVisbility=DEFAULTдо@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)где принимаются любые модификаторы доступа-это;- изменить
ObjectMapperглобально, установивobjectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);. Этого следует избегать, если вам не нужна эта функциональность глобально.выберите на основе ваших потребностей.
SpringBoot2. 0 ,я разрешаю его следующим кодом:
@Bean public ObjectMapper objectMapper() { return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);}
Comments