今天帮助同事调试一个问题,说fastjson在序列化的时候是忽略大小写的,有测试代码,但是不知道为什么,我帮他看了下,特意将过程记录在这个地方。
Bean定义如下:
public class Person{ private int id; private String name; public int getId(){return id;} public void setId(int id){this.id = id;} public String getName(){return name;} public void setName(String name){this.name = name;}
JSON转换的代码如下:
String text = "{\"id\":123,\"NAME\":\"chris\"}"; Person bean = JSON.parSEObject(text,Person.class); System.out.println(JSON.toJSONString(bean));
这个属性是能赋值成功的,看到json里面的key是NAME,而bean的属性是name,可以赋值成功。
我在解决问题的时候,发现既然能赋值成功,我们可以在setName上面加一个断点,就可以看到整个调用栈了,最后发现在ASMJavaBeanDeserializer类里面有下面的逻辑使得它可以忽略大小写查找。
public boolean parseField(DefaultJSONParser parser,String key,Object object,Type objectType,Map<String,Object> fieldValues) { JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx Map<String,FieldDeserializer> feildDeserializerMap = serializer.getFieldDeserializerMap(); FieldDeserializer fieldDeserializer = feildDeserializerMap.get(key); if (fieldDeserializer == null) { for (Map.Entry<String,FieldDeserializer> entry : feildDeserializerMap.entrySet()) { if (entry.getKey().equalsIgnoreCase(key)) { fieldDeserializer = entry.getValue(); break; } } } if (fieldDeserializer == null) { if (!parser.isEnabled(Feature.IgnoreNotMatch)) { throw new JSONException("setter not found,class " + serializer.getClass() + ",property " + key); } lexer.nextTokenWithColon(); parser.parse(); // skip return false; } lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken()); fieldDeserializer.parseField(parser,object,objectType,fieldValues); return true; }
可以发现,在从map中获取到fieldDeserializer为空的时候,还在进行一次忽略大小写的比较,既可以拿到值。
这个地方,在调试的时候,发现这个map类型为IdentityHashMap,关于这个的用法和源码,请参考我的另外一个博客