I. Preface
In the development process often encountered JSON parsing and generation problems, so you have been using Fastjson to achieve this function.
However, a recent problem has been encountered:
Many of the data inside the JSON string are "_" underlined, for example, op_id.
And in Java, a lot of the hump is written, such as Opid
Can these two match and then parse?
Two. Workaround for HTTP requests
The HTTP request has a @jsonproperty annotation, but this annotation, Fastjson, is not recognized.
Three. Smart Matching
Fastjson provides smart matching rules, which are automatically mapped
Op_id->opid->ipid
This means that even if the JSON string is ' op_id ', the Java variable can be opid or opid, and then the corresponding data can be obtained.
As follows:
public class Runme {static int one_day_seconds = $ * $ * 1000;public static void Main (string[] args) {String json = "{\" op-id\ ": 1000}"; Mo mo = json.parseobject (JSON, Mo.class); System.out.println (Mo.getopid ());} public static class Mo {private string Opid;public string Getopid () {return opid;} public void Setopid (String opid) {this.opid = Opid;}}}
Four. Principle Analysis
How did the Fastjson do it?
Read the next source code
Https://github.com/alibaba/fastjson
The logic of discovering it is as follows:
Files: Src/main/java/com/alibaba/fastjson/parser/deserializer/javabeandeserializer.java
Method: Smartmatch (String key, int[] setflags)
Public fielddeserializer smartmatch (string key, int[] setflags) { if (key == null) { return null; } fielddeserializer fielddeserializer = getfielddeserializer (key, setflags); if (fielddeserializer == null) { long smartkeyhash = typeutils.fnv1a_64_lower (Key); if (this.smartmatchhasharray == null) { long[] hashArray = new long[sortedfielddeserializers.length]; for (int i = 0; i < sortedfielddeserializers.length; i++) { hasharray[i] = typeutils.fnv1a_64_lower ( Sortedfielddeserializers[i].fieldinfo.name); } arrays.sort (Hasharray); this.smartMatchHashArray = hashArray; } // smartmatchhasharraymapping int pos = Arrays.binarysearch (Smartmatchhasharray, smartkeyhash); boolean is = false; if (pos < 0 && (Is = key.startswith ("is" ))) { Smartkeyhash = typeutils.fnv1a_64_lower (key.substring (2)); pos = arrays.binarysearch (SmartMatchHashArray, smartkeyhash); } if (pos >= 0) { if (Smartmatchhasharraymapping == null) { short[] mapping = new short[smartMatchHashArray.length]; Arrays.fill (mapping, (short) -1); for (int i = 0; i < sortedfielddeserializers.length; i++) { int p = arrays.binarysearch (smartmatchhasharray , Typeutils.fnv1a_64_lower (sortedfielddeserializers[i].fieldinfo.name)); if (p >= 0) { &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;MAPPING[P] = (short) i; } } Smartmatchhasharraymapping = mapping; } int deserindex = smartMatchHashArrayMapping[pos]; if (deserindex != -1) { if (!issetflag (Deserindex, setflags)) { fieldDeserializer = sortedfielddeserializers[deserindex]; } } } if (fielddeserializer != null) { FieldInfo fieldInfo = fielddeserializer.fieldinfo; if ((Fieldinfo.parserfeatures & feature.disablefieldsmartmatch.mask) != 0) { return null; } Class fieldClass = fieldInfo.fieldClass; if (is && (fieldclass != Boolean.class && fieldclass != boolean.class)) { fielddeserializer = null; } } } return fielddeserializer; }
An important part of this is calling the Typeutils.fnv1a_64_lower (String) method, calculating the incoming key (op_id) and the defined Java member variable opid, and then calculating whether they match.
If it matches, it will be overwritten.
So the key is to implement the Typeutils.fnv1a_64_lower (String) method, as follows:
This method is if it is ' _ ' or '-', then ignore, that is, if it is op_id, then it will become opid.
If it is uppercase, then it is converted to lowercase, that is, opid, it becomes opid.
So Op-id or op_id can match opid or opid.
Public static long fnv1a_64_lower (String key) { long hashcode = 0xcbf29ce484222325l; for ( Int i = 0; i < key.length (); ++i) { char ch = key.charat (i); if (ch == ' _ ' | | ch == '-') { continue; } if (ch >= ' A ' && ch <= ' Z ') { ch = (char) (CH&NBSP;+&NBSP;32); } hashCode ^= ch; hashCode *= 0x100000001b3L; } return hashcode; }
This article is from the "www.bogo.com" blog, make sure to keep this source http://483181.blog.51cto.com/473181/1981575
Fastjson. Methods and source code analysis for the processing of underline and hump problems