Gson Bijective Reflection

Gson extension for stricter class deserialization in Kotlin and Java

License

License

Categories

Categories

Gson Data JSON
GroupId

GroupId

io.github.dzirbel
ArtifactId

ArtifactId

gson-bijectivereflection
Last Version

Last Version

2.0.0
Release Date

Release Date

Type

Type

pom.sha512
Description

Description

Gson Bijective Reflection
Gson extension for stricter class deserialization in Kotlin and Java
Project URL

Project URL

https://github.com/dzirbel/gson-bijectivereflection
Source Code Management

Source Code Management

https://github.com/dzirbel/gson-bijectivereflection

Download gson-bijectivereflection

Dependencies

compile (1)

Group / Artifact Type Version
org.jetbrains.kotlin : kotlin-stdlib-jdk8 jar 1.4.21

runtime (3)

Group / Artifact Type Version
com.google.code.gson : gson jar 2.8.6
org.jetbrains.kotlin : kotlin-reflect jar 1.4.21
com.google.code.findbugs : jsr305 jar 3.0.2

Project Modules

There are no modules declared in this project.

Gson Bijective Reflection

Build codecov Maven Central

gson-bijectivereflection is an extension to Gson for Kotlin and Java which adds stricter deserialization of user-provided classes.

It adds a BijectiveReflectiveTypeAdapterFactory which requires that JSON deserialization of classes is bijective:

  • all non-nullable fields in the destination class must be present in the JSON (surjective)
  • all JSON elements must be mapped to fields on the destination class; no JSON elements can be unused (injective, kind of)

(BijectiveReflectiveTypeAdapterFactory is customizable, including to require only surjectivity or injectivity)

This library can be used to make your JSON deserialization more strict, in order to verify that your class models closely reflect the input JSON. It is particularly useful for testing; for example, if you inject your Gson object, you can configure only your tests to use the BijectiveReflectiveTypeAdapterFactory and your production code to be more lenient.

WARNING: While gson-bijectivereflection is a small library, it depends on Kotlin reflection, which is a large (~3 MB) artifact. This may restrict its usage in space-constrained contexts, such as Android apps.

Download

Gradle (Groovy DSL):

dependencies {
    implementation 'io.github.dzirbel.gson-bijectivereflection:2.0.0'
}

Gradle (Kotlin DSL):

dependencies {
    implementation("io.github.dzirbel.gson-bijectivereflection:2.0.0")
}

Maven:

<dependency>
    <groupId>io.github.dzirbel</groupId>
    <artifactId>gson-bijectivereflection</artifactId>
    <version>2.0.0</version>
</dependency>

Usage

To apply the BijectiveReflectiveTypeAdapterFactory, supply it when building your Gson object:

import io.github.dzirbel.gson.bijectivereflection.BijectiveReflectiveTypeAdapterFactory

val gson = GsonBuilder()
    .registerTypeAdapterFactory(BijectiveReflectiveTypeAdapterFactory())
    .create()

That's it! The BijectiveReflectiveTypeAdapterFactory will be used to deserialize JSON into classes for this gson, and can be configured further via constructor parameters. It will throw a JsonSyntaxException when deserializing (i.e. gson.fromJson(...)) JSON that doesn't meet the bijective criteria. See the class documentation for more details.

Examples

// Class:
class Example1(val stringField: String, val intField: Int)

// JSON:
{ stringField: "string value", intField: 123 }

IS bijective.


// Class:
class Example2(val stringField: String, val intField: Int, val nullableStringField: String?)

// JSON:
{ stringField: "string value", intField: 123 }

IS still bijective, since nullableStringField has a nullable type String?.


// Class:
class Example3(val stringField: String, val intField: Int)

// JSON:
{ stringField: "string value", intField: 123, anotherField: ["another", "value"] }

IS NOT bijective, since anotherField does not have a corresponding field in Example3.


// Class:
class Example4(val stringField: String, val intField: Int)

// JSON:
{ stringField: "string value" }

IS NOT bijective, since Example4.intField does not have a value in the JSON. By default Gson would leave intField as null, which can lead to unexpected NullPointerExceptions in Kotlin, since it is of the non-nullable type Int.


// Java class:
class Example5 {
    String stringField;
    @Nullable String nullableString;
}

// JSON:
{ stringField: "string value" }

IS bijective, since @Nullable can be used like Kotlin nullability to denote that the field is not required in the JSON.

License

gson-bijectivereflection is provided under the MIT License.

Versions

Version
2.0.0
1.0.0