Why Using `success` Instead of `isSuccess` Prevents JSON Serialization Bugs in Java
Choosing the correct boolean property name in JavaBeans—using `success` rather than `isSuccess`—ensures consistent getter/setter generation and avoids mismatched JSON serialization across frameworks like fastjson, Gson, and Jackson, preventing subtle bugs in production environments.
Background
In everyday development a boolean field is often used to indicate whether a request succeeded, e.g., a
successflag exposed through an RPC interface.
JavaBeans Naming Rules
The JavaBeans specification defines getters and setters for normal properties as
getPropertyName()and
setPropertyName(value). For boolean properties the getter must be named
isPropertyName()while the setter remains
setPropertyName(boolean).
<code>public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);
public boolean is<PropertyName>();
public void set<PropertyName>(boolean m);
</code>Problem When the Field Itself Is Named isSuccess
If a field is declared as
private boolean isSuccess;, IDEs often generate a getter named
isSuccess()and a setter named
setSuccess(boolean). This works at compile time but creates ambiguity for JSON‑serialization libraries that rely on JavaBeans introspection.
<code>class Model implements Serializable {
private static final long serialVersionUID = 1836697963736227954L;
private boolean isSuccess;
public boolean isSuccess() { return isSuccess; }
public void setSuccess(boolean success) { isSuccess = success; }
public String getHollis() { return "hollischuang"; }
}
</code>Serialization Differences
The following test serializes a
Modelinstance with three popular libraries.
<code>public class BooleanMainTest {
public static void main(String[] args) throws IOException {
Model model = new Model();
model.setSuccess(true);
System.out.println("Serializable Result With fastjson :" + JSON.toJSONString(model));
Gson gson = new Gson();
System.out.println("Serializable Result With Gson :" + gson.toJson(model));
ObjectMapper om = new ObjectMapper();
System.out.println("Serializable Result With jackson :" + om.writeValueAsString(model));
}
}
</code>Output:
<code>Serializable Result With fastjson :{"hollis":"hollischuang","success":true}
Serializable Result With Gson :{"isSuccess":true}
Serializable Result With jackson :{"success":true,"hollis":"hollischuang"}
</code>fastjson and Jackson discover the
isSuccess()method, interpret the property name as
success, and therefore produce a JSON field
success. Gson, on the other hand, inspects the field directly and emits
isSuccess.
Deserialization Mismatch
When the JSON produced by fastjson (or Jackson) is fed back to Gson, Gson looks for a field named
success, cannot find it, and leaves the boolean at its default value
false:
<code>public class BooleanMainTest {
public static void main(String[] args) throws IOException {
Model model = new Model();
model.setSuccess(true);
Gson gson = new Gson();
System.out.println(gson.fromJson(JSON.toJSONString(model), Model.class));
}
}
</code>Result:
<code>Model[isSuccess=false]
</code>This discrepancy can cause serious production bugs because the object state after a round‑trip is no longer what was originally set.
Recommendation
Define the field as
private boolean success;and keep the getter
isSuccess(). This follows the JavaBeans convention correctly, yields the same property name (
success) for all serialization frameworks, and eliminates the inconsistency.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.