PCSalt
YouTube GitHub
Back to Java
Java · 4 min read

JSON Parsing in Java — Which Library Should You Use?

A side-by-side comparison of org.json, Gson, Moshi, and Jackson for JSON parsing in Java — with recommendations for Android, backend, and new projects.


This is the final post in the JSON Parsing in Java series. We’ve parsed the same complex JSON response with four different libraries — now it’s time to put them head to head and figure out which one you should actually use.

Looking for the Kotlin version? Read it here.

Quick Recap

Throughout this series, we parsed the same SaaS API response — users, subscriptions, teams, pagination, nullable fields, dates, and nested objects. Here’s how each library approached it:

org.json — Manual parsing. You call getString(), getInt(), getBoolean() for every field. Null checks with optString() or isNull(). Array loops everywhere. About 100 lines of parsing code for one response.

Gson — Define your model classes, call fromJson(), and you’re done. Gson maps JSON keys to field names automatically. Nullable fields just work. Custom date handling needs a TypeAdapter.

Moshi — Similar to Gson but more modern. Uses @Json annotations for field mapping, adapters for custom types, and has first-class Kotlin support. Stricter about nullability.

Jackson — The most feature-rich option. Uses ObjectMapper with @JsonProperty annotations. Built-in support for Java 8 date/time types via modules. The default choice for Spring Boot.

Side-by-Side Comparison

Featureorg.jsonGsonMoshiJackson
Lines to parse our JSON~100~5~5~5
Null handlingManual (isNull(), optString())Automatic (fields set to null)Strict (fails on unexpected nulls with Kotlin)Automatic (configurable)
Date/time supportNone (manual Instant.parse())Needs custom TypeAdapterNeeds custom JsonAdapterBuilt-in via jackson-datatype-jsr310 module
Streaming supportNoYes (JsonReader/JsonWriter)Yes (JsonReader/JsonWriter)Yes (JsonParser/JsonGenerator)
Android friendlinessBuilt into Android SDKGood (widely used)Excellent (designed for Android)Heavy (works but large dependency)
Bundle size0 KB (built-in on Android)~250 KB~150 KB~1.7 MB (core + annotations + databind)
Kotlin supportSame as JavaWorks but no null safetyExcellent (kotlin-codegen, null safe)Works via jackson-module-kotlin
Maintenance statusInfrequent updatesMaintenance mode (bug fixes only)Active (Square)Active (FasterXML)
Learning curveLow (just get/set)LowLow-MediumMedium-High

Code Comparison

Let’s see the core parse call for the same JSON string in all four libraries. Assume model classes are already defined.

org.json

import org.json.JSONObject;

JSONObject root = new JSONObject(jsonString);
String status = root.getString("status");
JSONObject data = root.getJSONObject("data");
// ... then manually extract every single field

Gson

import com.google.gson.Gson;

Gson gson = new Gson();
ApiResponse response = gson.fromJson(jsonString, ApiResponse.class);

Moshi

import com.squareup.moshi.Moshi;
import com.squareup.moshi.JsonAdapter;

Moshi moshi = new Moshi.Builder().build();
JsonAdapter<ApiResponse> adapter = moshi.adapter(ApiResponse.class);
ApiResponse response = adapter.fromJson(jsonString);

Jackson

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
ApiResponse response = mapper.readValue(jsonString, ApiResponse.class);

The difference is pretty clear. org.json requires you to write the mapping logic yourself. The other three do it automatically — you just define the model and call one method.

When to Use What

Android app with Retrofit

Use Moshi. It was built by Square specifically for this use case. Small footprint, null-safe with Kotlin, and Retrofit has a Moshi converter out of the box. Gson is also a solid choice if your project already uses it.

Spring Boot backend

Use Jackson. It’s already included in Spring Boot’s starter dependencies. Spring auto-configures the ObjectMapper for you. Fighting against Jackson to use something else in Spring would be working against the framework.

Quick scripts or one-off parsing

Use org.json. If you just need to pull a couple of fields out of a JSON string and don’t want to define model classes, org.json is the fastest way to get there. No model classes needed — just getString() and go.

New projects (greenfield)

Use Moshi for Android or Jackson for backend. If you’re writing Kotlin, also consider Kotlin Serialization — it’s a first-party solution with compile-time safety. Avoid Gson for new projects since it’s in maintenance mode and won’t get new features.

Performance Considerations

A few general guidelines (not benchmarks — those depend heavily on your payload size and structure):

  • org.json is the slowest for complex parsing because everything is manual, but for simple key lookups on small JSON, it’s perfectly fast.
  • Jackson has the fastest raw throughput for large payloads, especially with its streaming API. It also handles large files well because you can parse without loading everything into memory.
  • Gson and Moshi are comparable for typical payloads. Moshi is slightly faster in most real-world scenarios because of its more efficient internal design.
  • For most apps, parsing speed doesn’t matter. Network latency dwarfs JSON parse time. Pick the library that makes your code cleanest and most maintainable.
  • If performance truly matters: use the streaming API of whichever library you choose. All three (Gson, Moshi, Jackson) support it.

Using in Android

Here’s a quick summary of how each library fits into Android development:

LibraryAndroid Recommendation
org.jsonBuilt-in. Good for quick one-off parsing. Not great for full API layers.
GsonWorks well. Widely used in older Android projects. Add com.google.code.gson:gson to your Gradle dependencies.
MoshiBest choice for new Android projects. Small JAR, Kotlin-friendly, pairs perfectly with Retrofit and OkHttp. Add com.squareup.moshi:moshi to your Gradle dependencies.
JacksonWorks but heavy. The combined size of jackson-core, jackson-annotations, and jackson-databind adds ~1.7 MB to your APK. Use only if you have a specific reason.

For a typical Android setup with Retrofit and Moshi:

implementation 'com.squareup.moshi:moshi:1.15.2'
implementation 'com.squareup.retrofit2:converter-moshi:2.11.0'

For Gson with Retrofit:

implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.squareup.retrofit2:converter-gson:2.11.0'

Wrapping Up

There’s no single “best” JSON library for Java — it depends on your context. But if you need a quick decision tree:

  1. Already using Spring Boot? Jackson. It’s already there.
  2. Android app? Moshi (or Gson if already in the project).
  3. Need to parse one field from a JSON string? org.json.
  4. Starting fresh? Moshi for Android, Jackson for backend.

The most important thing is consistency — pick one and use it across your project. Mixing libraries is a recipe for confusion.

Looking for Kotlin? The same comparison with Kotlin Serialization included is here.