In front of the source code, there is no secret. Hello, I'm the class representative. Official account search: Java class representatives, get more Java dry cargo in time.
Ali development specification Taishan Edition (April 22, 2020) – > programming protocol – > (I) naming style – > Article 8 stipulates:
[mandatory] no Boolean variables in POJO class should be prefixed with is, otherwise some framework parsing will cause serialization errors.
For such a [mandatory] level regulation, although it is simply explained in the specification, it still seems very inconspicuous, so that although I am familiar with the specification, I still stepped on this pit.
0 cause
Recently, I wrote a nail alarm tool class. For this task with clear requirements and clear development documents, I wrote code at my fingertips and finished it soon.
However, during the self-test, it was found that @ everyone's interface could not pass the unit test. After some tracking, the reason was finally found, so this article came out.
1 problem recurrence
Sending a nailing message is a post request, and the nailing is endorsed by Ali, so it can't be called. That's naturally a problem for me as a developer.
The following is the description of the nailing interface. The parameter isAtAll indicates whether @ owner
{ "msgtype": "text", "text": { "content": "I am me, It's different fireworks@156xxxx8827" }, "at": { "atMobiles": [ "156xxxx8827", "189xxxx8325" ], "isAtAll": false } }
According to this json string, I write the following POJO classes corresponding to it, and use fastjson for json serialization
public class Message { /** * Message type **/ private String msgtype = "text"; /** * Message content object **/ private Text text; /** * The @ object **/ private At at; public static class At{ /** * Called by @ person **/ private List<String> atMobiles; /** * Is it @ owner **/ private boolean isAtAll; // Omit getter and setter } // Omit irrelevant code }
The problem lies in private boolean isAtAll; In this field, is it found that Ali's parameter violates the development specification mentioned at the beginning? After serialization with fastjson, the attribute is actually converted to:
"atAll": true
This pit father's goods, eat the is in front! Unable to @ everyone
2 tracing the source
Why eat is after serialization? With this problem, I traced the source code of fastjson and found that when serializing, the getter method name of the attribute is used, and the getter and setter automatically generated by isAtAll field are:
public boolean isAtAll() { return isAtAll; } public void setAtAll(boolean atAll) { isAtAll = atAll; }
The opposite method name in the corresponding fastjson is handled in com alibaba. fastjson. util. TypeUtils. In computegetters, the source code excerpt is as follows:
if(methodName.startsWith("is")){ if(methodName.length() < 3){ continue; } if(method.getReturnType() != Boolean.TYPE && method.getReturnType() != Boolean.class){ continue; } String propertyName; Field field = null; if(Character.isUpperCase(c2)){ if(compatibleWithJavaBean){ propertyName = decapitalize(methodName.substring(2)); } else{ propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3); } propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 2); }
In other words, for methods starting with is, fastjson intercepts the third character first. If the character is uppercase, it is converted to lowercase, and the remaining method names are assembled to form the attribute name.
For example, the attribute name assembled by isAtAll method is atAll, and the final result is to put our is
Here you go!
3 solution
Now that the root cause of the problem has been found, we just need to apply the right medicine to the case. Here, the class representative summarizes three solutions for different application scenarios:
- For the code with modification permission, the development specifications shall be strictly followed. The boolean type attribute in POJO class shall not be named beginning with is. If yes, it shall be changed
- For the third-party interface, there are parameters like isXXX in the parameters. You can use @ jsonfield (name = "othername") of fastjson on the corresponding attribute field to customize the attribute name
- getter and setter method names can be modified manually
4 extension
SpringBoot integrates jackson. jackson is used by default for json serialization. After testing, jackson also eats is. The principle is similar to fastjson, so I won't explain it too much. Just follow the solutions mentioned in the article in the development process
reference resources
- fastjson source code
- Ali development specification Taishan Edition (April 22, 2020)
[recommended in previous periods]
Use Spring Validation to gracefully validate parameters
Is the downloaded attachment name always garbled? You should read the RFC document!
Explain MySQL priority queue in simple terms (order by limit problem you will step on)
The original codeword is not easy. Welcome to like, pay attention and share.
Search: Java class representative, waiting for your attention.