{"id":19337257,"url":"https://github.com/infobip/infobip-jackson-extension","last_synced_at":"2025-04-23T01:30:56.344Z","repository":{"id":48877270,"uuid":"287212669","full_name":"infobip/infobip-jackson-extension","owner":"infobip","description":"Library which provides new features for (de)serialization on top of Jackson library.","archived":false,"fork":false,"pushed_at":"2024-06-26T10:10:46.000Z","size":162,"stargazers_count":5,"open_issues_count":1,"forks_count":3,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-02T06:12:20.839Z","etag":null,"topics":["jackson-databind","jackson-library","serialization"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/infobip.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-13T07:35:32.000Z","updated_at":"2024-06-26T10:10:50.000Z","dependencies_parsed_at":"2024-06-26T11:26:22.562Z","dependency_job_id":null,"html_url":"https://github.com/infobip/infobip-jackson-extension","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-jackson-extension","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-jackson-extension/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-jackson-extension/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-jackson-extension/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/infobip","download_url":"https://codeload.github.com/infobip/infobip-jackson-extension/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250352196,"owners_count":21416454,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jackson-databind","jackson-library","serialization"],"created_at":"2024-11-10T03:13:51.592Z","updated_at":"2025-04-23T01:30:56.002Z","avatar_url":"https://github.com/infobip.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Infobip Jackson Extension\n\n![](https://github.com/infobip/infobip-jackson-extension/workflows/maven/badge.svg)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.infobip/infobip-jackson-extension-spring-boot-starter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.infobip/infobip-jackson-extension-spring-boot-starter)\n[![Coverage Status](https://coveralls.io/repos/github/infobip/infobip-jackson-extension/badge.svg?branch=master)](https://coveralls.io/github/infobip/infobip-jackson-extension?branch=master)\n[![Known Vulnerabilities](https://snyk.io/test/github/infobip/infobip-jackson-extension/badge.svg)](https://snyk.io/test/github/infobip/infobip-jackson-extension)\n\nLibrary which provides new features for (de)serialization on top of [Jackson library](https://github.com/FasterXML/jackson).\n\n## Contents\n\n1. [Changelog](#Changelog)\n1. [Setup](#Setup)\n1. [Features](#Features)\n    * [Simple json hierarchy](#SimpleJsonHierarchy)\n    * [Overriding type json property name](#OverridingTypeJsonPropertyName)\n    * [Lower case type value](#LowerCaseTypeValue)\n    * [Multi level hierarchies](#MultiLevelHierarchies)\n      * [Hierarchy per property approach](#HierarchyPerPropertyApproach)\n      * [Single property approach](#SinglePropertyApproach)\n    * [Parallel hierarchies](#ParallelHierarchies)\n    * [Typeless (present property)](#Typeless)\n    * [Dynamic hierarchy](#DynamicHierarchy)\n    * [Single Argument Property Creator annotationless support](#SingleArgumentPropertyCreatorAnnotationlessSupport)\n\n\u003ca id=\"Changelog\"\u003e\u003c/a\u003e\n## Changelog\n\nFor changes check the [changelog](CHANGELOG.md).\n\n\u003ca id=\"Setup\"\u003e\u003c/a\u003e\n## Setup\n\nAll examples have corresponding tests and additional usage examples can be found in tests.\n\nIn examples, tests and [Single Argument Property Creator annotationless support](#SingleArgumentPropertyCreatorAnnotationlessSupport) it's required that \nthe code is compiled with `-parameters` compiler option and that `jackson-module-parameter-names` module is used.\n\nParameter names module:\n```xml\n\u003cdependency\u003e\n   \u003cgroupId\u003ecom.fasterxml.jackson.module\u003c/groupId\u003e\n   \u003cartifactId\u003ejackson-module-parameter-names\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\nCompiler plugin setup:\n```xml\n\u003cplugin\u003e\n\t\u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n\t\u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n\t\u003cversion\u003e${maven-compiler-plugin.version}\u003c/version\u003e\n\t\u003cconfiguration\u003e\n       ...\n\t\t\u003ccompilerArgument\u003e-parameters\u003c/compilerArgument\u003e\n\t\t\u003ctestCompilerArgument\u003e-parameters\u003c/testCompilerArgument\u003e\n       ...\n\t\u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n\nParameter names module makes parameter names visible to the Jackson meaning it can map json properties to constructor parameter names so there's no redundant \nJackson annotation to redeclare them. There's an important catch here: JSON field name, Java accessors and constructor parameter name all must match!\n\n### Spring Boot\n\nJust include the following dependency:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.infobip\u003c/groupId\u003e\n    \u003cartifactId\u003einfobip-jackson-extension-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e${infobip-jackson-extension.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Without Spring Boot\n\nInclude the following dependency:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.infobip\u003c/groupId\u003e\n    \u003cartifactId\u003einfobip-jackson-extension-module\u003c/artifactId\u003e\n    \u003cversion\u003e${infobip-jackson-extension.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nRegister the module with `ObjectMapper`:\n\n```java\nobjectMapper.registerModule(new InfobipJacksonModule());     \n```\n\n\u003ca id=\"Features\"\u003e\u003c/a\u003e\n## Features\n\n\u003ca id=\"SimpleJsonHierarchy\"\u003e\u003c/a\u003e\n### Simple json hierarchy\n\nFor models that have a type represented by an enum you can use simple typed json approach:\n\n```java\ninterface FooBar extends SimpleJsonHierarchy\u003cFooBarType\u003e {\n}\n\nrecord Foo(String foo) implements FooBar {\n\n   @Override\n   public FooBarType getType() {\n      return FooBarType.FOO;\n   }\n\n}\n\nrecord Bar(String bar) implements FooBar {\n\n   @Override\n   public FooBarType getType() {\n      return FooBarType.BAR;\n   }\n\n}\n\n@Getter\n@AllArgsConstructor\nenum FooBarType implements TypeProvider\u003cFooBar\u003e {\n   FOO(Foo.class),\n   BAR(Bar.class);\n\n   private final Class\u003c? extends FooBar\u003e type;\n}\n```\n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/SimpleJsonHierarchyDeserializerTest.java)\n\n\u003ca id=\"OverridingTypeJsonPropertyName\"\u003e\u003c/a\u003e\n#### Overriding type json property name\n\nName of the property can be overridden:\n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/CustomTypeFieldSimpleJsonHierarchyTest.java)\n\n\u003ca id=\"LowerCaseTypeValue\"\u003e\u003c/a\u003e\n#### Lower case type value\n\nCasing of the property type value can be overridden:\n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/LowerCaseTypeSimpleJsonHierarchyTest.java)\n\n\u003ca id=\"MultiLevelHierarchies\"\u003e\u003c/a\u003e\n### Multi level hierarchies\n\nMulti level hierarchies are supported with 2 different approach.\n\nThe first approach is used when there is a property per hierarchy.\n\nThe second approach is used when only one property is shared, but property values are globally unique, meaning \nthere can't be two hierarchies that have the same property value. \nIf values were not unique, it would be unclear to which class to deserialize.\n\nNote that these examples have simplified sub hierarchies for brevity of the documentation, but you can use different \nmechanisms previously defined for specific sub hierarchy - e.g. one hierarchy can use the default type property\nbut another one can [override type json property name](#OverridingTypeJsonPropertyName).\n\n\u003ca id=\"HierarchyPerPropertyApproach\"\u003e\u003c/a\u003e\nWhen there is a property per hierarchy following can be used:\n\n```java\n@JsonTypeResolveWith(AnimalJsonTypeResolver.class)\ninterface Animal {\n    AnimalType getAnimalType();\n}\n\nstatic class AnimalJsonTypeResolver extends SimpleJsonTypeResolver\u003cAnimalType\u003e {\n    public AnimalJsonTypeResolver() {\n        super(AnimalType.class, \"animalType\");\n    }\n}\n\n@JsonTypeResolveWith(MammalJsonTypeResolver.class)\ninterface Mammal extends Animal {\n    MammalType getMammalType();\n}\n\nstatic class MammalJsonTypeResolver extends SimpleJsonTypeResolver\u003cMammalType\u003e {\n\n    public MammalJsonTypeResolver() {\n        super(MammalType.class, \"mammalType\");\n    }\n}\n\nrecord Human(String name) implements Mammal {\n\n   @Override\n   public AnimalType getAnimalType() {\n      return AnimalType.MAMMAL;\n   }\n\n   @Override\n   public MammalType getMammalType() {\n      return MammalType.HUMAN;\n   }\n\n}\n\n@Getter\n@AllArgsConstructor\nenum AnimalType implements TypeProvider\u003cAnimal\u003e {\n   MAMMAL(Mammal.class);\n\n   private final Class\u003c? extends Animal\u003e type;\n}\n\n@Getter\n@AllArgsConstructor\nenum MammalType implements TypeProvider\u003cMammal\u003e {\n   HUMAN(Human.class);\n\n   private final Class\u003c? extends Mammal\u003e type;\n}\n```\n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/MultiHierarchyJsonTypedDeserializerTest.java)\n\n\u003ca id=\"SinglePropertyApproach\"\u003e\u003c/a\u003e\nWhen there is a single property shared for all hierarchies following can be used:\n\n```java\nsealed interface Animal extends SealedSimpleJsonHierarchies {\n\n}\n\nsealed interface Bird extends Animal, SimpleJsonHierarchy\u003cBirdType\u003e {\n\n}\n\n@Getter\n@AllArgsConstructor\nenum BirdType implements TypeProvider\u003cBird\u003e {\n   PARROT(Parrot.class);\n\n   private final Class\u003c? extends Bird\u003e type;\n}\n\nrecord Parrot() implements Bird {\n\n   @Override\n   public BirdType getType() {\n      return BirdType.PARROT;\n   }\n}\n\nsealed interface Mammal extends Animal, SimpleJsonHierarchy\u003cMammalType\u003e {\n\n}\n\n@Getter\n@AllArgsConstructor\nenum MammalType implements TypeProvider\u003cMammal\u003e {\n   HUMAN(Human.class);\n\n   private final Class\u003c? extends Mammal\u003e type;\n}\n\nrecord Human(String name) implements Mammal {\n\n   @Override\n   public MammalType getType() {\n      return MammalType.HUMAN;\n   }\n}\n```\n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/SealedSimpleJsonHierarchiesTest.java)\n\n\u003ca id=\"ParallelHierarchies\"\u003e\u003c/a\u003e\n### Parallel hierarchies\n\nIn case you have multiple hierarchies that reuse the same enum TypeProvider can present an issue, use this approach to as a guide to possible solution:\n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/ParallelHierarchyJsonTypedDeserializerTest.java).\n\n\u003ca id=\"Typeless\"\u003e\u003c/a\u003e\n### Typeless (present property)\n\nIn case you don't want to (or can't - third party API) include type information in json, you can use this approach:\n\n```java\ninterface Bike extends PresentPropertyJsonHierarchy\u003cBikeType\u003e {\n}\n\nrecord RoadBike(String roadBike) implements Bike {\n}\n\nrecord Bmx(String bmx) implements Bike {\n}\n\n@Getter\n@AllArgsConstructor\nenum BikeType implements TypeProvider\u003cBike\u003e {\n   ROAD_BIKE(RoadBike.class),\n   BMX(Bmx.class);\n\n   private final Class\u003c? extends Bike\u003e type;\n}\n```\n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/PresentPropertyDeserializerTest.java).\n\nNotice that by default snake cased type names are translated to camel case properties (e.g. `ROAD_BIKE` -\u003e `roadBike`).\nIf you want to use different casing you can provide your own resolver by extending `PresentPropertyJsonTypeResolver`:\n```java\nstatic class LowerUnderscorePresentPropertyJsonTypeResolver\u003cE extends Enum\u003cE\u003e \u0026 TypeProvider\u003e extends PresentPropertyJsonTypeResolver\u003cE\u003e {\n\n    public LowerUnderscorePresentPropertyJsonTypeResolver(Class\u003cE\u003e type) {\n        super(type, CaseFormat.LOWER_UNDERSCORE);\n    }\n}\n```\nThen your model may look as follows:\n```java\n@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)\n@JsonTypeResolveWith(LowerUnderscorePresentPropertyJsonTypeResolver.class)\ninterface Bike extends PresentPropertyJsonHierarchy\u003cBikeType\u003e {\n\n}\n\nstatic class LowerUnderscorePresentPropertyJsonTypeResolver\u003cE extends Enum\u003cE\u003e \u0026 TypeProvider\u003cE\u003e\u003e\n        extends PresentPropertyJsonTypeResolver\u003cE\u003e {\n\n   public LowerUnderscorePresentPropertyJsonTypeResolver(Class\u003cE\u003e type) {\n      super(type, CaseFormat.LOWER_UNDERSCORE);\n   }\n}\n\nrecord RoadBike(String roadBike) implements Bike {\n\n}\n\nrecord MountainBike(String mountainBike) implements Bike {\n\n}\n``` \nNotice standard jackson `@JsonNaming` annotation in `Bike` interface.  \n\n[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/PresentPropertyCaseFormatDeserializerTest.java).\n\n\u003ca id=\"DynamicHierarchy\"\u003e\u003c/a\u003e\n### Dynamic hierarchy\n\nIn case root of the hierarchy is decoupled from the leaves in different compilation units.\nAlso it can be seen as annotationless alternative.\n\n[Showcase without type provider](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/dynamic/DynamicHierarchyDeserializerTest.java).\n\n[Showcase with type provider](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/dynamic/DynamicHierarchyDeserializerWithTypeProviderTest.java).\n\nIn case Spring Boot starter is used you only need to register DynamicHierarchyDeserializer as a @Bean, starter handles wiring with Jackson.\n\n\u003ca id=\"SingleArgumentPropertyCreatorAnnotationlessSupport\"\u003e\u003c/a\u003e\n### Single Argument Property Creator annotationless support\n\nThis module also adds support for deserializing single property value objects when using parameter names module:\n\n```java\nclass Foo {\n    private final Bar bar;\n\n    Foo(Bar bar) {\n        this.bar = bar;\n    }\n}\n```\n\nwithout any additional configuration or annotations.\nRelated issues: https://github.com/FasterXML/jackson-databind/issues/1498, https://github.com/spring-projects/spring-boot/issues/26023.\n\n## \u003ca id=\"Requirements\"\u003e\u003c/a\u003e Requirements:\n\n- Java 17\n\n## \u003ca id=\"Contributing\"\u003e\u003c/a\u003e Contributing\n\nIf you have an idea for a new feature or want to report a bug please use the issue tracker.\n\nPull requests are welcome!\n\n## \u003ca id=\"License\"\u003e\u003c/a\u003e License\n\nThis library is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfobip%2Finfobip-jackson-extension","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfobip%2Finfobip-jackson-extension","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfobip%2Finfobip-jackson-extension/lists"}