Why and How to Replace Fastjson with Gson in Large Java Projects

This article explains why fastjson is being abandoned due to frequent security vulnerabilities, compares fastjson, Jackson, and Gson, and provides practical migration strategies, code examples, performance considerations, and common pitfalls to help teams safely switch to Gson in enterprise Java applications.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Why and How to Replace Fastjson with Gson in Large Java Projects

Why abandon fastjson?

The main reason is the frequent security vulnerabilities of fastjson, which force the company to repeatedly upgrade the library across all business lines.

Fastjson alternatives

The article focuses on using Gson to replace fastjson and briefly mentions Jackson as another option.

Characteristics of three JSON frameworks

Fastjson

Fast performance, historically unmatched by other Java JSON libraries.

Widely used in large-scale deployments (e.g., Alibaba).

Extensive test cases ensure stability.

Simple API.

Jackson

Easy to use with a high‑level API.

No need to create explicit mappings for most objects.

High performance and low memory usage.

Produces clean, compact JSON.

Only depends on the JDK.

Gson

Simple conversion between Java objects and JSON.

Supports immutable objects.

Allows custom object representations.

Handles complex object graphs.

Outputs lightweight, readable JSON.

Performance comparison

Single‑object serialization: Fastjson > Jackson > Gson.

Large‑object serialization: Jackson > Fastjson > Gson.

Single‑object deserialization: Fastjson > Jackson > Gson (small gap).

Large‑object deserialization: Fastjson > Jackson > Gson (small gap).

Final selection

Jackson is suitable for high‑performance scenarios; Gson is suitable for high‑security scenarios.

New projects should avoid fastjson. For existing systems, consider migration cost and choose among:

Migration considerations

Large enterprise projects have complex codebases, multiple maintainers, and critical online services, making fastjson‑to‑Gson migration challenging.

Be cautious

Any mistake can cause severe production issues; thorough planning and communication are essential.

Coordinate development and testing

Plan module‑by‑module replacement, schedule carefully, and ensure both developers and testers understand version and API changes.

Regression and interface testing

Allocate sufficient testing effort for full regression and, if possible, interface‑level comparison of JSON responses.

Performance impact

Assess performance differences, especially for high‑traffic services, to avoid unexpected latency changes.

Using Gson to replace Fastjson

Two common JSON handling methods with code examples are provided to help developers quickly adopt Gson.

JSON deserialization

String jsonCase = "[{\"id\":10001,\"date\":1609316794600,\"name\":\"小明\"},{\"id\":10002,\"date\":1609316794600,\"name\":\"小李\"}]";
// fastjson
JSONArray jsonArray = JSON.parseArray(jsonCase);
System.out.println(jsonArray);
System.out.println(jsonArray.getJSONObject(0).getString("name"));
System.out.println(jsonArray.getJSONObject(1).getString("name"));
// Gson
JsonArray jsonArrayGson = gson.fromJson(jsonCase, JsonArray.class);
System.out.println(jsonArrayGson);
System.out.println(jsonArrayGson.get(0).getAsJsonObject().get("name").getAsString());
System.out.println(jsonArrayGson.get(1).getAsJsonObject().get("name").getAsString());

Both frameworks handle empty objects and arrays without errors.

Generic type handling

// Entity class
User user = new User();
user.setId(1L);
user.setUserName("马云");
// fastjson
List<User> listFastjson = JSONArray.parseArray(JSON.toJSONString(userList), User.class);
List<User> listFastjson2 = JSON.parseObject(JSON.toJSONString(userList), new TypeReference<List<User>>(){});
// Gson
List<User> listGson = gson.fromJson(gson.toJson(userList), new TypeToken<List<User>>(){}.getType());

Gson also supports generics.

List/Map writing

// fastjson
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("user", user);
jsonObject1.put("userList", userList);
System.out.println(jsonObject1);
// Gson
JsonObject jsonObject = new JsonObject();
jsonObject.add("user", gson.toJsonTree(user));
System.out.println(jsonObject);

Gson requires explicit conversion of objects to JSON trees before adding them to a JsonObject.

CamelCase ↔ snake_case conversion

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
Gson gsonUnderScore = gsonBuilder.create();
System.out.println(gsonUnderScore.toJson(user));

Outputs fields like {"id":1,"user_name":"马云"}.

Common pitfalls

Date serialization differences

Fastjson serializes Date as Unix timestamps, while Gson uses standard date formats, causing deserialization errors.

Date serialization difference
Date serialization difference
public class MyDateTypeAdapter extends TypeAdapter<Date> {
    @Override
    public void write(JsonWriter out, Date value) throws IOException {
        if (value == null) {
            out.nullValue();
        } else {
            out.value(value.getTime());
        }
    }
    @Override
    public Date read(JsonReader in) throws IOException {
        if (in != null) {
            return new Date(in.nextLong());
        } else {
            return null;
        }
    }
}
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new MyDateTypeAdapter()).create();

SpringBoot mapper conflict

Switching to Gson may cause HttpMessageNotWritableException because SpringBoot defaults to Jackson.

spring.mvc.converters.preferred-json-mapper=gson

Swagger incompatibility

Gson integration can break Swagger JSON generation; adding a custom GsonHttpMessageConverter resolves the issue.

@Configuration
public class GsonSwaggerConfig {
    @Bean
    public IGsonHttpMessageConverter IGsonHttpMessageConverter() {
        return new IGsonHttpMessageConverter();
    }
}

Using JsonObject as a request parameter

Gson parses numeric fields as double, which may lead to unexpected values (e.g., 0 becomes 0.0). Prefer using strongly‑typed DTOs or custom adapters.

Conclusion

The article provides a comprehensive guide for teams needing to migrate from fastjson to Gson, covering security motivations, performance trade‑offs, migration steps, and solutions to common issues such as Date handling, SpringBoot configuration, Swagger integration, and numeric precision.

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.

securityFastJSONGsonjson migration
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

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.