is boolean attribute serialization problem

Posted by superaktieboy on Mon, 17 Jan 2022 00:26:36 +0100

If the property of JavaBean class is of boolean type, the format of its reading method can be isXxx() or getXxx(). For example, the reading method of a boolean type property named state can be isState() or getState().

[mandatory] any boolean variable in POJO class should not be prefixed with is, otherwise partial framework resolution will cause sequence
Chemical error.
Counterexample: the attribute defined as the basic data type Boolean isDeleted, and its method is isDeleted(). During reverse parsing, the framework "mistakenly thinks" the corresponding attribute name is deleted, resulting in failure to obtain the attribute, and then throws an exception.

1, Get method automatically generated by Boolean IDE

  1. is boolean
public class testBoolean {
	private boolean isTestBoolean;
	
	public boolean isTestBoolean() {
		return isTestBoolean;
	}
}
  1. Non is boolean
public class testBoolean {
	private boolean testBoolean;
	
	public boolean isTestBoolean() {
		return testBoolean;
	}
}

For the boolean attribute of the basic data type, whether the attribute name starts with is or not, the getter method automatically generated by the IDE is isXxx().

2, Differences between Gson, Jackson and fastjason serialization

Test class

static class TestJsonBoolean {

        private boolean isBooTest;

        // getter method automatically generated by IDE
        public boolean isBooTest() {
            return isBooTest;
        }

        public void setBooTest(boolean booTest) {
            isBooTest = booTest;
        }

        // Property that does not exist in the class
        public String getTestAtt() {
            return "testatt";
        }
    }

Class is initialized with Gson, Jackson and fastjason respectively.

public static void main(String[] args) throws JsonProcessingException {
        TestJsonBoolean test = new TestJsonBoolean();
        test.setBooTest(true);

        String gJson = new Gson().toJson(test);// Gson serialization
        String jJson = new ObjectMapper().writeValueAsString(test); // Jackson serialization
        String fJson = JSON.toJSONString(test);// Fastjason serialization

        System.out.println("GsonToJson:" + gJson);
        System.out.println("JacksonToJson:" + jJson);
        System.out.println("FastJsonToJson:" + fJson);
    }

Output results

GsonToJson:{"isBooTest":true}
JacksonToJson:{"booTest":true,"testAtt":"testatt"}
FastJsonToJson:{"booTest":true,"testAtt":"testatt"}

It can be seen that the serialization methods of the three serialization tools are still different. Gson serializes according to the attributes in the class, so the result is no problem. The serialization method of Jackson and fastjason is to find the getter method first, and then generate the corresponding attribute name according to the JavaBean specification. Therefore, not only the isBooTest attribute is serialized into booTest, but also the attributes that do not exist in the testAtt class are in the serialization result.

3, Problems arising

Test class

static class TestJsonBoolean {

        private boolean isBooTest;

        // getter method automatically generated by IDE
        public boolean isBooTest() {
            return isBooTest;
        }

        public void setBooTest(boolean booTest) {
            isBooTest = booTest;
        }

        @Override
        public String toString() {
            return "TestJsonBoolean{" +
                    "isBooTest=" + isBooTest +
                    '}';
        }
    }

Deserialize Jackson or fastjason serialization results using Gson

public static void main(String[] args) throws JsonProcessingException {
        TestJsonBoolean test = new TestJsonBoolean();
        test.setBooTest(true);

        // Serialization using Jackson
        String jJson = new ObjectMapper().writeValueAsString(test);
        System.out.println("JacksonToJson:" + jJson);
        // Deserialize Jackson's serialization results using Gson
        System.out.println("JsonToObj:" + new Gson().fromJson(jJson, TestJsonBoolean.class));

    }

Output results

JacksonToJson:{"booTest":true}
JsonToObj:TestJsonBoolean{isBooTest=false}

When Gson is used to deserialize the serialization result of Jackson or fastjason, because the isBooTest attribute is serialized as booTest in the serialization result, Gson does not find the attribute when deserializing it, and the basic data type is given the default value of false, resulting in inconsistent results before and after serialization.

4, Summary

Do not name the boolean type attribute in the class, starting with is, which is also clearly explained in Ali's development manual.

Topics: Java JSON