Fast, reflection-free Json binding via apt source code generation. A light (~200kb + generated code) source code generation style alternative to Jackson's ObjectMapper or Gson. (code generation vs reflection)
- Annotate java classes with 
@Json(or use@Json.Importfor types we "don't own" or can't annotate) avaje-jsonb-generatorannotation processor generates Java source code to convert to/from json- No need to manually register generated adapters. (Uses ServiceLoader to auto-register)
 - Constructors and accessors/getters/setters of any style "just work" (records, constructors, 'fluid setters')
 - Jackson-like annotations: 
@Json.Raw,@Json.Property,@Json.Ignore,@Json.Alias, etc. - Support Imports and Mixins (adding jsonb features to types we can't directly annotate).
 - Supports Generic Types.
 - Provides support for dynamic json views (similar in style to that presented by LinkedIn at java one in 2009
 - One of the top three fastest Java JSON libraries
 
Built-in support for reading and writing Java’s core data types:
- Primitives (int, float, char...) and their boxed counterparts (Integer, Float, Character...).
 - BigInteger and BigDecimal
 - java.time classes (Instant, LocalDate, LocalDateTime...)
 - Arrays, Collections, Streams, Lists, Sets, and Maps
 - Optionals (will unwrap and serialize the contained value)
 - Strings
 - Enums
 - Other miscellaneous types (UUID, URL, URI)
 
<dependency>
  <groupId>io.avaje</groupId>
  <artifactId>avaje-jsonb</artifactId>
  <version>${avaje-jsonb-version}</version>
</dependency>And add avaje-jsonb-generator as an annotation processor.
<dependency>
  <groupId>io.avaje</groupId>
  <artifactId>avaje-jsonb-generator</artifactId>
  <version>${avaje-jsonb-version}</version>
  <scope>provided</scope>
</dependency>Add @Json to the types we want to serialize.
The avaje-jsonb-generator annotation processor will generate a JsonAdapter as java source code
for each type annotated with @Json. These will be automatically registered with Jsonb
when it is started using a service loader mechanism.
@Json
public class Address {
  private String street;
  private String suburb;
  private String city;
  // object fields will automatically have adapters generated, no @Json required
  // (though you can add @Json anyway to modify the generated adapter how you wish)
  private OtherClass other;
  //add getters/setters
}This also works with records:
@Json
public record Address(String street, String suburb, String city) { }For types we cannot annotate with @Json we can place @Json.Import(TypeToimport.class) on any class/package-info to generate the adapters.
// build using defaults
Jsonb jsonb = Jsonb.instance();
JsonType<Customer> customerType = jsonb.type(Customer.class);
Customer customer = ...;
// serialize to json
String asJson = customerType.toJson(customer);
// deserialize from json
Customer customer = customerType.fromJson(asJson);avaje-jsonb supports dynamic json views. This allows us to specify which specific properties
to include when serializing to json.
For example:
Jsonb jsonb = Jsonb.instance();
JsonType<Customer> customerType = jsonb.type(Customer.class);
// only including the id and name
JsonView<Customer> idAndNameView = customerType.view("(id, name)");
String asJson = idAndNameView.toJson(customer);
JsonView<Customer> myView =
  customerType.view("(id, name, billingAddress(*), contacts(lastName, email))");
// serialise to json the above specified properties only
String asJson = myView.toJson(customer);Given the class:
@Json
public class Address {
  private String street;
  private City city;
  private Suburb suburb;
  //getters/setters ommited for brevity
}The following code will be generated and used for serialization/deserialization.
@Generated
public final class AddressJsonAdapter implements JsonAdapter<Address>, ViewBuilderAware {
  private final JsonAdapter<String> stringJsonAdapter;
  private final JsonAdapter<City> cityJsonAdapter;
  private final JsonAdapter<Suburb> suburbJsonAdapter;
  private final PropertyNames names;
  public AddressJsonAdapter(Jsonb jsonb) {
    this.stringJsonAdapter = jsonb.adapter(String.class);
    this.cityJsonAdapter = jsonb.adapter(City.class);
    this.suburbJsonAdapter = jsonb.adapter(Suburb.class);
    this.names = jsonb.properties("street", "city", "suburb");
  }
  @Override
  public boolean isViewBuilderAware() {
    return true;
  }
  @Override
  public ViewBuilderAware viewBuild() {
    return this;
  }
  @Override
  public void build(ViewBuilder builder, String name, MethodHandle handle) {
    builder.beginObject(name, handle);
    builder.add("street", stringJsonAdapter, builder.method(Address.class, "getStreet", java.lang.String.class));
    builder.add("city", cityJsonAdapter, builder.method(Address.class, "getCity", City.class));
    builder.add("suburb", suburbJsonAdapter, builder.method(Address.class, "getSuburb", Suburb.class));
    builder.endObject();
  }
  @Override
  public void toJson(JsonWriter writer, Address address) {
    writer.beginObject(names);
    writer.names(names);
    writer.name(0);
    stringJsonAdapter.toJson(writer, address.getStreet());
    writer.name(1);
    cityJsonAdapter.toJson(writer, address.getCity());
    writer.name(2);
    suburbJsonAdapter.toJson(writer, address.getSuburb());
    writer.endObject();
  }
  @Override
  public Address fromJson(JsonReader reader) {
    Address _$address = new Address();
    // read json
    reader.beginObject(names);
    while (reader.hasNextField()) {
      final String fieldName = reader.nextField();
      switch (fieldName) {
        case "street": {
          _$address.setStreet(stringJsonAdapter.fromJson(reader)); break;
        }
        case "city": {
          _$address.setCity(cityJsonAdapter.fromJson(reader)); break;
        }
        case "suburb": {
          _$address.setSuburb(suburbJsonAdapter.fromJson(reader)); break;
        }
        default: {
          reader.unmappedField(fieldName);
          reader.skipValue();
        }
      }
    }
    reader.endObject();
    return _$address;
  }
}avaje-jsonb was based on Moshi with some changes as summarised below:
- Generates Java source code (rather than Kotlin)
 - Uses custom parser inspired by 
dsl-json(with option of usingjackson-core'sJsonParserandJsonGeneratoras parsers) - Has no fallback to reflection - jsonb is code generation or bust.
 - JsonReader - Make JsonReader an interface, default implementation using 
Jsonb JsonReadAdapter - JsonWriter - Make JsonWriter an interface, default implementation using 
Jsonb JsonWriteAdapter - JsonAdapter -> Make JsonAdapter an interface.
 - Moshi -> Jsonb - Rename Moshi to Jsonb and make it an interface
 - Moshi.Builder -> Jsonb.Builder - Basically the same but Jsonb.Builder as interface plus added Component and AdapterBuilder
 - Add JsonType for a more friendly API to use rather than the underlying JsonAdapter
 - Add Jsonb.Component interface - allows easy service loading of adapters
 - Additionally, it generates a Jsonb.Component and uses service loading to auto-register all generated adapters. This means there is no need to register the generated adapters manually.
 - Add fromObject() as a "covert from object" feature like Jackson ObjectMapper
 - Add naming convention support
 - Add 
@Json.Importto generate adapters for types that we can't put the annotation on (types we might not 'own') - Add support for generating adapters (for 
@Json.Imported types) with annotations from Jackson, GSON and Jakarta - Add Mixin feature similar to Jackson Mixins
 - Add Types.listOf(), Types.setOf(), Types.mapOf() helper methods
 - Adds more common Java types with default built-in support - java.time types, java.util.UUID
 - Adds support for json views
 
When using @Json.Import for types we "don't own", we provide basic support for annotations from other popular libraries.
Simply add either jackson-annotations, gson or jakarta.json.bind-api, and use @Json.Import to generate an adapter.
| Avaje Jsonb | Jackson | Gson | Jakarta JSON-B | 
|---|---|---|---|
@Json.Alias | 
@JsonAlias | 
@SerializedName(alternate=…) | 
— | 
@Json.Creator | 
@JsonCreator | 
— | @JsonbCreator | 
@Json.Ignore | 
@JsonIgnore | 
@Expose(serialize = false) | 
@JsonbTransient | 
@Json.Property | 
@JsonProperty | 
@SerializedName | 
@JsonbProperty | 
@Json.Raw | 
@JsonRawValue | 
— | — | 
@Json.Value | 
— | — | — | 
When using Spring Web, you can use the following dependency to use avaje-jsonb for HTTP serialization:
<dependency>
  <groupId>io.avaje</groupId>
  <artifactId>avaje-jsonb-spring-starter</artifactId>
  <version>${avaje-jsonb-version}</version>
</dependency>