Jackson‑jr in Spring Boot: Lightning‑Fast JSON Serialization & Benchmarks

This article introduces the lightweight Jackson‑jr library for Java, demonstrates how to create JSON objects and arrays, use the Composer API, customize serialization with annotations, and presents JMH performance comparisons showing Jackson‑jr’s superior speed over Jackson‑databind and Gson in Spring Boot 3.4.2 environments.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Jackson‑jr in Spring Boot: Lightning‑Fast JSON Serialization & Benchmarks

1. Introduction

Jackson‑jr is a lightweight JSON processing library for Java, offering a smaller footprint and faster startup than the full Jackson library, making it suitable for micro‑services, mobile apps, and embedded systems.

2. Practical Example

Environment

Spring Boot 3.4.2

Dependencies

<dependency>
  <groupId>org.openjdk.jmh</groupId>
  <artifactId>jmh-core</artifactId>
  <version>${jmh.version}</version>
</dependency>
<dependency>
  <groupId>org.openjdk.jmh</groupId>
  <artifactId>jmh-generator-annprocess</artifactId>
  <version>${jmh.version}</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.jr</groupId>
  <artifactId>jackson-jr-all</artifactId>
  <version>2.18.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.18.2</version>
</dependency>
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.12.1</version>
</dependency>

Basic Usage – Creating Objects and Arrays

Jackson‑jr provides a convenient API for building JSON objects and arrays using standard Java collections.

Map<String, Object> data = Map.of(
  "name", "Pack",
  "age", 30,
  "email", "[email protected]"
);
String json = JSON.std
    .with(JSON.Feature.PRETTY_PRINT_OUTPUT)
    .asString(data);
System.err.println(json);

Output:

{
  "email" : "[email protected]",
  "age" : 30,
  "name" : "Pack"
}

Composer API

The Composer interface offers a builder‑style way to generate JSON.

public static void composerJson() throws Exception {
    String json = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
        .composeString()
        .startObject()
        .startArrayField("users")
            .startObject()
                .put("name", "pack").put("age", 30)
            .end()
            .startObject()
                .put("name", "xg").put("age", 31)
            .end()
        .end()
        .startArrayField("hobby")
            .add(1).add(2).add(3)
        .end()
        .startObjectField("address")
            .put("province", "新疆").put("city", "乌鲁木齐")
        .end()
        .put("other", true)
        .finish();
    System.err.println(json);
}

Output:

{
  "users" : [
    {"name":"pack","age":30},
    {"name":"xg","age":31}
  ],
  "hobby" : [1,2,3],
  "address" : {"province":"新疆","city":"乌鲁木齐"},
  "other" : true
}

Serialization & Deserialization

Jackson‑jr can serialize and deserialize complex object graphs.

public static void serialization() throws Exception {
    User user = new User("pack", 33);
    String json = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
        .asString(user);
    System.err.println(json);
    json = """
        {"name": "pack_xg", "age": 33}
        """;
    User u = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
        .beanFrom(User.class, json);
    System.err.println(u);
}

Output:

{
  "age" : 33,
  "name" : "pack"
}
User [name=pack_xg, age=33]

Custom Serialization

Annotations such as @JsonProperty allow fine‑grained control over field names, formats, and inclusion of null values.

User user = new User("pack");
JSON jsonMapper = JSON.std
    .with(JSON.Feature.PRETTY_PRINT_OUTPUT)
    .with(JSON.Feature.WRITE_NULL_PROPERTIES)
    .with(JSON.Feature.FAIL_ON_DUPLICATE_MAP_KEYS);
String json = jsonMapper.asString(user);
System.err.println(json);

Performance Comparison

JMH benchmarks compare Jackson‑jr, Jackson‑databind, and Gson for serialization speed.

@Warmup(iterations = 3, time = 1)
@Fork(value = 1, jvmArgsAppend = {"-Xms512m", "-Xmx512m"})
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
@State(Scope.Benchmark)
@Threads(1)
public class JacksonJRTest {
  @Benchmark
  public void jacksonJr(Blackhole hole) throws Exception {
    JSON std = JSON.std;
    User user = new User("pack", 25);
    String json = std.asString(user);
    hole.consume(json);
  }
  @Benchmark
  public void jacksonObjectMapper(Blackhole hole) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    User user = new User("pack", 25);
    String json = mapper.writeValueAsString(user);
    hole.consume(json);
  }
  @Benchmark
  public void gson(Blackhole hole) throws Exception {
    Gson gson = new Gson();
    User user = new User("pack", 25);
    String json = gson.toJson(user);
    hole.consume(json);
  }
}

Result:

The benchmark shows that Jackson‑jr outperforms the other two libraries, offering significantly higher serialization speed in suitable scenarios.

End of article.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaperformance benchmarkJSONSpring BootJackson-jr
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.