Jackson - JsonMappingException (geen serializer gevonden voor klasse)

1. Overzicht

In deze korte tutorial analyseren we het rangschikken van entiteiten zonder getters en de oplossing voor de Jackson JsonMappingException uitzondering.

Als je dieper wilt graven en leren andere coole dingen die je kunt doen met de Jackson 2 - ga naar de belangrijkste Jackson-tutorial.

2. Het probleem

Standaard werkt Jackson 2 alleen met velden die openbaar zijn of een openbare getter-methode hebben - serialiseren van een entiteit die alle velden privé of pakket privé heeft, zal mislukken:

openbare klasse MyDtoNoAccessors {String stringValue; int intValue; boolean booleanValue; openbare MyDtoNoAccessors () {super (); } // geen getters}
@Test (verwacht = JsonMappingException.class) public void givenObjectHasNoAccessors_whenSerializing_thenException () gooit JsonParseException, IOException {String dtoAsString = nieuw ObjectMapper (). WriteValueAsString (nieuw MyDtoNo )Accessors (nieuw MyDtoNo )Accessors; assertThat (dtoAsString, notNullValue ()); }

De volledige uitzondering is:

com.fasterxml.jackson.databind.JsonMappingException: geen serializer gevonden voor klasse dtos.MyDtoNoAccessors en geen eigenschappen gevonden om BeanSerializer te maken (om uitzondering te voorkomen, schakel SerializationFeature.FAIL_ON_EMPTY_BEANS uit))

3. De oplossing

De voor de hand liggende oplossing is om getters voor de velden toe te voegen - als de entiteit onder onze controle staat. Als dat niet het geval is en het wijzigen van de bron van de entiteit is niet mogelijk - dan geeft Jackson ons een paar alternatieven.

3.1. Wereldwijd automatisch velden detecteren met elke zichtbaarheid

Een eerste oplossing voor dit probleem is om het ObjectMapper om alle velden te detecteren, ongeacht hun zichtbaarheid:

objectMapper.setVisibility (PropertyAccessor.FIELD, Visibility.ANY);

Dit zal sta toe dat de privé- en pakket-privévelden worden gedetecteerd zonder getters, en serialisatie zal correct werken:

@Test openbare leegte gegevenObjectHasNoAccessors_whenSerializingWithAllFieldsDetected_thenNoException () gooit JsonParseException, IOException {ObjectMapper objectMapper = nieuwe ObjectMapper (); objectMapper.setVisibility (PropertyAccessor.FIELD, Visibility.ANY); String dtoAsString = objectMapper.writeValueAsString (nieuwe MyDtoNoAccessors ()); assertThat (dtoAsString, bevatString ("intValue")); assertThat (dtoAsString, bevatString ("stringValue")); assertThat (dtoAsString, bevatString ("booleanValue")); }

3.2. Alle velden gedetecteerd op klassenniveau

Een andere optie die Jackson 2 biedt, is - in plaats van de algemene configuratie - controle over de zichtbaarheid van het veld op klasniveau via de @JsonAutoDetect annotatie:

@JsonAutoDetect (fieldVisibility = Visibility.ANY) openbare klasse MyDtoNoAccessors {...}

Met deze annotatie zou de serialisering nu correct moeten werken met deze specifieke klasse:

@Test openbare leegte gegevenObjectHasNoAccessorsButHasVisibleFields_whenSerializing_thenNoException () gooit JsonParseException, IOException {ObjectMapper objectMapper = nieuwe ObjectMapper (); String dtoAsString = objectMapper.writeValueAsString (nieuwe MyDtoNoAccessors ()); assertThat (dtoAsString, bevatString ("intValue")); assertThat (dtoAsString, bevatString ("stringValue")); assertThat (dtoAsString, bevatString ("booleanValue")); }

4. Conclusie

Dit artikel illustreert hoe omzeil de standaard zichtbaarheid van het veld in Jackson, door een aangepaste zichtbaarheid ofwel globaal te configureren op het ObjectMapper of op individuele lessen. Jackson maakt zelfs nog meer maatwerk mogelijk door opties te bieden om precies te bepalen hoe getters, setters of velden met specifieke zichtbaarheid door de mapper worden gezien.

De implementatie van al deze voorbeelden en codefragmenten is te vinden in mijn GitHub-project - dit is een op Eclipse gebaseerd project, dus het zou gemakkelijk moeten kunnen worden geïmporteerd en uitgevoerd zoals het is.


$config[zx-auto] not found$config[zx-overlay] not found