-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The json conversion to the entity object data binding part is unsuccessful. #2327
Comments
Huh? I think what I need here is FULL Java object declaration -- all "@getter" and "@Setter" annotations (Lombok?) expanded, and then explain why you think something is wrong. And also see if enabling |
Is a getter, setter method generated by lombook, because the getter generated by lombook, setter method and eclipse generated getter, setter method name is a little different, but I look at the source code of jackson found that jackson in the generation of json entity attribute name is through setter The method name interception operation obtained, there is a case difference in the generated json attribute name. I tested alibaba fastjson, google gson, generated json, whether it is gelipse generated getter, setter, or lombook generated getter , setter , generated json is the same, but jackson is different in the case of two kinds of getter, setter Since fastjson is the default json parsing framework for spring, if the following example appears, the backend will receive less data. for example : @getter
}` `import org.springframework.web.bind.annotation.PostMapping; @RestController If I send a post request to the test method, the requested data json is If I send a post request to the test method, the requested data json is The background did not receive tEst, tDate data, ttttttDate data received normally, I also tried to set the parameter MapperFeature.USE_STD_BEAN_NAMING, but it is not useful, if I set the spring json converter to alibaba fastjson, google gson, all data can be Normal reception |
First, it seems the getters/setters generated by Eclipse (menu Source>Generate Getters and Setters...) are a bit awkward for tDate and tEst. It seems it's due (bug or feature) to Eclipse not handling properly the only 1st lowercase character.
|
@hj819748949 @cowtowncoder So if you "fix" the wrong getters and setters as:
Then with this setup:
you get: By adding:
you get: |
Ok. As far as I can see, the result is as expected in both cases. The problem in matching stems from discrepancy between field names and setters/getters: the way Jackson works in figuring out implied property names is:
and then applying possible annotations, and finally combining all accessors by derived names. In this case getter/setter names do not result in matches. This is the way it is, and it looks like Lombok is using bit different algorithm in deriving getter/setter names from fields, using what seems like a reasonable algorithm but producing irreversible names -- so from
it is impossible to uniquely get back to Unfortunately I do not think I can change anything in Jackson to easily handle this case at least for Jackson 2.x. But even further, handling of case-insensitive names reliably is a difficult undertaking (and possibly incurring significant overhead for runtime) since after rewriting name unification to do case-insensitive matching (to get to full set of accessors) it would then be necessary to either:
So. There is no trivial fix and none will be added for 2.x. For 3.x I could consider improvement to do name-insensitive matching during property introspection. |
I'm sorry, but I don't understand the first part about the "discrepancy", and the way Jackson works. Further reading about led me to this issue: FasterXML/jackson-module-kotlin#92 which points to an answer on StackOverflow explaining the "problem": https://stackoverflow.com/a/30207335 (+ original blog post: http://futuretask.blogspot.com/2005/01/java-tip-6-dont-capitalize-first-two.html ) Seems like it's rather a strange coding of the Afterall, as noticed in this comment https://stackoverflow.com/questions/2948083/naming-convention-for-getters-setters-in-java#comment34902684_16146215 under another StackOverflow question about the same matter, the
Not the other way round (i.e. taking a variable name and convert it to standard getter/setter <PropertyName>). |
I am sorry but I can't explain in more detail. The way Jackson determines names to use starts -- and must start -- from combination of method/field names, and match them (not knowing which one would be "correct"), whereas Lombok starts with specific field name and converts to method. But at this point there is no simple change to Jackson that would help here: to resolve this particular issue, case-insensitive reconciliation would need to be implemented. I have no plans to do that. So you will either need to change naming convention used for fields, or add annotations to make sure fields/methods match. |
version: 2.9.4
// entity example:
@getter
@Setter
public class User{
private String tDate;
private String tEst;
private String ttttttDate;
}
// test example
@test
public void testObjToJson() throws JsonProcessingException
{
ObjectMapper mapper = new ObjectMapper();
User user = new User();
user.setTDate("wfrefreg");
user.setTEst("dwefref");
String mapJakcson = mapper.writeValueAsString(user);
}
result:
{"ttttttDate":"xxxx","tdate":"wfrefreg","test":"dwefref"}
The actual result wants to be:
{"ttttttDate":"xxxx","tDate":"wfrefreg","tEst":"dwefref"}
After debugging the source code, I found
com.fasterxml.jackson.databind.util.BeanUtil.legacyManglePropertyName
protected static String legacyManglePropertyName(final String basename, final int offset)
{
.......
for (; i < end; ++i) {
c = basename.charAt(i);
d = Character.toLowerCase(c);
if (c == d) {
sb.append(basename, i, end);
break;
}
// This place should be wrong.
// Should be modified into sb.append(c);
sb.append(d);
}
}
The text was updated successfully, but these errors were encountered: