fastjson反fastjson 序列化对象时如果实例有多个引用时有Bug

FastJson序列化的时候忽略大小写的细节研究 - 勤奋的asialee的博客 - ITeye博客
博客分类:
今天帮助同事调试一个问题,说fastjson在序列化的时候是忽略大小写的,有测试代码,但是不知道为什么,我帮他看了下,特意将过程记录在这个地方。
Bean定义如下:
public class Person{
public int getId(){}
public void setId(int id){this.id =}
public String getName(){}
public void setName(String name){this.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();
if (fieldDeserializer == null) {
if (!parser.isEnabled(Feature.IgnoreNotMatch)) {
throw new JSONException("setter not found, class " + serializer.getClass() + ", property " + key);
lexer.nextTokenWithColon();
parser.parse(); // skip
lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken());
fieldDeserializer.parseField(parser, object, objectType, fieldValues);
可以发现,在从map中获取到fieldDeserializer为空的时候,还在进行一次忽略大小写的比较,既可以拿到值。
这个地方,在调试的时候,发现这个map类型为IdentityHashMap,关于这个的用法和源码,请参考我的另外一个博客
浏览: 807686 次
来自: 北京
为什么会intMap.get(&bbb&) ...
感觉LogManager打开了所有的LogSegment(文件 ...匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。JSONObject.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.mmm";
Productorder tmp1 = JSONObject.parseObject(tmp.toJSONString(), Productorder.class);
方案2:新增date反序列化解析器
主要思路是以fastjson原生的DateDeserializer.class为基础,定制化一个可以解析的日期反序列化解析器。该方式是fastjson函数JSON.parseObject()的一个应用场景,通过定制化ParserConfig参数,达到局部改变JSON解析逻辑的目的。如下:
package jeromechan.fixbug.fastjson;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.deserializer.DateDeserializer;
import java.lang.reflect.Type;
* Copyright ?0?8 2016 Jerome Chan. All rights reserved.
* An extended DateDeseializer for parsing ''.
* @author chenjinlong
* @CreateDate 7/20/16 5:55 PM
public class JCDateDeserializer extends DateDeserializer {
public static final JCDateDeserializer instance = new JCDateDeserializer();
public JCDateDeserializer() {
protected &T& T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object val)
if (val == null) {
return null;
} else if (val instanceof String) {
String strVal = (String) val;
if (strVal.length() == 0) {
return null;
} else if (strVal.equals("")) {
parser.setDateFormat("yyyy-MM-dd");
return super.cast(parser, clazz, fieldName, val);
// 示例执行例子
public class TestDemo {
public static String jsonStr = "{\"dateStr\":\"\"}";
public static void main(String[] args) {
ParserConfig jcParserConfig = new ParserConfig();
jcParserConfig.putDeserializer(Date.class, JCDateDeserializer.instance);
DateBeanDemo resultObject = JSON.parseObject(TestDemo.jsonStr, DateBeanDemo.class, jcParserConfig, JSON.DEFAULT_PARSER_FEATURE);
假设觉得这种解析办法可以作为整个项目内的全局特性,感兴趣的话可以将定制好的JCDateDeserializer利用spring框架注入到项目容器中。这同样是对于方案2很不错的延伸。
阅读(...) 评论()java中fastjson生成和解析json数据(序列化和反序列化数据)
作者:PointNet
字体:[ ] 类型:转载 时间:
本篇文章主要介绍了java中fastjson生成和解析json数据(序列化和反序列化数据),具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
本文讲解2点:
1. fastjson生成和解析json数据
(举例:4种常用类型:JavaBean,List&JavaBean&,List&String&,List&Map&String,Object&)
2.通过一个android程序测试fastjson的用法。
fastjson简介:
Fastjson是一个Java语言编写的高性能功能完善的JSON库。fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson。并且还超越了google的二进制协议protocol buf。Fastjson完全支持的标准,也是官方网站收录的参考实现之一。支持各种JDK类型。包括基本类型、JavaBean、Collection、Map、Enum、泛型等。支持JDK 5、JDK 6、Android、阿里云手机等环境。
一. fastjson生成json字符串(JavaBean,List&JavaBean&,List&String&,List&Map&String,Object&)
String jsonStrng = JSON.toJSONString(object);
二. fastjson 解析json字符串为四种类型
1. JavaBean
Person person = JSON.parseObject(jsonString, Person.class);
2. List&JavaBean&
List&Person& listPerson =JSON.parseArray(jsonString, Person.class);
3. List&String&
List&String& listString = JSON.parseArray(jsonString, String.class);
4. List&Map&String,Object&&
List&Map&String, Object&& listMap = JSON.parseObject(jsonString, new TypeReference&List&Map&String,Object&&&(){});&
(注意:此处可看出fastjson反射机制比gson更准确, id = 1001 通过fastjson反射仍是 id = 1001 , 而通过gson反射结果 为 id =1001.0 ,&
JSON解析器fastjson(阿里巴巴出品,版本1.1.26),如果定义了JSONObject为{"JACKIE_ZHANG":"张学友","ANDY_LAU":"刘德华","LIMING":"黎明","Aaron_Kwok":"郭富城"},那么读取值时,KEY顺序无序,测试代码:
import comalibabafastjsonJSONO
* Created by wangzhenfei on 14-4-
public class FastJsonTest {
public static void main(String[] args){
String jsonStr = "{\"JACKIE_ZHANG\":\"张学友\",\"ANDY_LAU\":\"刘德华\",\"LIMING\":\"黎明\",\"Aaron_Kwok\":\"郭富城\"}" ;
//做5次测试
for(int i=0,j=5;i&j;i++)
JSONObject jsonObject = JSONObjectparseObject(jsonStr) ;
for(javautilMapEntry&String,Object& entry:jsonObjectentrySet()){
Systemoutprint(entrygetKey()+"-"+entrygetValue()+"\t");
Systemoutprintln();//用来换行
运行结果:
LIMING-黎明 Aaron_Kwok-郭富城JACKIE_ZHANG-张学友ANDY_LAU-刘德华
Aaron_Kwok-郭富城 ANDY_LAU-刘德华LIMING-黎明JACKIE_ZHANG-张学友
Aaron_Kwok-郭富城 JACKIE_ZHANG-张学友ANDY_LAU-刘德华LIMING-黎明
LIMING-黎明 ANDY_LAU-刘德华JACKIE_ZHANG-张学友Aaron_Kwok-郭富城
JACKIE_ZHANG-张学友 LIMING-黎明ANDY_LAU-刘德华Aaron_Kwok-郭富城
解决办法:定义为JSONArray,代码如下:
import comalibabafastjsonJSONA
* Created by wangzhenfei on 14-4-
public class FastJsonTest {
public static void main(String[] args){
String jsonStr = "[{\"JACKIE_ZHANG\":\"张学友\"},{\"ANDY_LAU\":\"刘德华\"},{\"LIMING\":\"黎明\"},{\"Aaron_Kwok\":\"郭富城\"}]" ;
//做5次测试
for(int i=0,j=5;i&j;i++)
JSONArray jsonArray = JSONArrayparseArray(jsonStr);
for(int k=0;k&jsonArraysize();k++){
Systemoutprint(jsonArrayget(k) + "\t");
Systemoutprintln();//用来换行
运行结果为:
{"JACKIE_ZHANG":"张学友"} {"ANDY_LAU":"刘德华"}{"LIMING":"黎明"}{"Aaron_Kwok":"郭富城"}
{"JACKIE_ZHANG":"张学友"} {"ANDY_LAU":"刘德华"}{"LIMING":"黎明"}{"Aaron_Kwok":"郭富城"}
{"JACKIE_ZHANG":"张学友"} {"ANDY_LAU":"刘德华"}{"LIMING":"黎明"}{"Aaron_Kwok":"郭富城"}
{"JACKIE_ZHANG":"张学友"} {"ANDY_LAU":"刘德华"}{"LIMING":"黎明"}{"Aaron_Kwok":"郭富城"}
{"JACKIE_ZHANG":"张学友"} {"ANDY_LAU":"刘德华"}{"LIMING":"黎明"}{"Aaron_Kwok":"郭富城"}
如果就想要定义为JSONObject,而不是JSONArray,可以选用其他JSON解析器,个人推荐使用google的gson,文档明显比fastjson好很多(从这里可以看出阿里巴巴和谷歌的差距):
import comgooglegsonJsonE
import comgooglegsonJsonO
import comgooglegsonJsonP
* Created by wangzhenfei on 14-4-
public class FastJsonTest {
public static void main(String[] args){
String jsonStr = "{\"JACKIE_ZHANG\":\"张学友\",\"ANDY_LAU\":\"刘德华\",\"LIMING\":\"黎明\",\"Aaron_Kwok\":\"郭富城\"}" ;
//做5次测试
for(int i=0,j=5;i&j;i++)
JsonObject jsonObject = (JsonObject) new JsonParser()parse(jsonStr);
for(javautilMapEntry&String,JsonElement& entry:jsonObjectentrySet()){
Systemoutprint(entrygetKey()+"-"+entrygetValue()+"\t");
Systemoutprintln();//用来换行
运行结果:
JACKIE_ZHANG-"张学友" ANDY_LAU-"刘德华" LIMING-"黎明" Aaron_Kwok-"郭富城"
JACKIE_ZHANG-"张学友" ANDY_LAU-"刘德华" LIMING-"黎明" Aaron_Kwok-"郭富城"
JACKIE_ZHANG-"张学友" ANDY_LAU-"刘德华" LIMING-"黎明" Aaron_Kwok-"郭富城"
JACKIE_ZHANG-"张学友" ANDY_LAU-"刘德华" LIMING-"黎明" Aaron_Kwok-"郭富城"
JACKIE_ZHANG-"张学友" ANDY_LAU-"刘德华" LIMING-"黎明" Aaron_Kwok-"郭富城"
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 redis fastjson序列化 的文章

 

随机推荐