fastjson,请注意大小写

前言:fastjson先生(后称之为F先生)由阿里巴巴集团荣誉出品,我的记忆中,伟大的阿里巴巴对于编程界,能够称之为贡献的也仅此而已,可见我是多么的孤陋寡闻。我的项目中也用到了F先生,我很器重他,并且他表现一直非常优秀,然而在对接华夏接口的过程中,我对F先生爱之深,责之切。当然原因不能单纯的归咎于F先生,可恶可怜的华夏接口可能才是祸害之源。

总结成果

经过一天时间的折磨,最终定位到华夏接口对于getter和setter方法书写上有点“非人类”,请看以下代码:
public String[] getschools() {//可恶的小写“s”
  return schools;
 }

 public void setschools(String[] schools) {
  this.schools = schools;
 }

经F先生路由后结果如下:
Student student = new Student();
  student.setName("lilei");
 
  String [] schools = new String[1];
  schools[0] = new String("21中");
 
  student.setschools(schools);
 
  String json = JSON.toJSONString(student);
  System.out.println(json);
  // {"name":"lilei"}

那么解决之道是什么,大家都能想得到了。
public String[] getSchools() {
  return schools;
 }

 public void setSchools(String[] schools) {
  this.schools = schools;
 }

Student student = new Student();
  student.setName("lilei");
 
  String [] schools = new String[1];
  schools[0] = new String("21中");
 
  student.setSchools(schools);
 
  String json = JSON.toJSONString(student);
  System.out.println(json);
  // {"name":"lilei","schools":["21中"]}

如果你认为你已经得到了答案,那么请跳过以下内容,不过我认为,如果你跳过了下面章节的阅读,你将得不偿失。

事件描述

在一个安静的傍晚,我一个人待在办公室做华夏接口的调试工作,虽然寂寞了点,但是还是非常开心,接口调试工作很顺利。然而风云突变,华夏接口施展了一招“天狗吞日”,瞬间我就迷茫了,出现了总结成果中的第一种情况。

时间一分一秒的过去了,我本着从自我原因找起的原则,不断审视着自己编写的代码,怀疑自己在对数组对象的赋值上面错误了,接着又怀疑自己在传递json数据时发生错误。。。最终并没有找到原因。

包大人上场

也许你看了总结成果后,感觉不就是一个大小写问题吗,我怎么还喋喋不休。然而个人能力的提升,就是要反复的总结,而后才能“得道”。

1. 怀疑自己的代码出错了
这永远都是应该的,从前至后,翻看自己的代码,看是否存在bug。发生这个数据丢失的问题后,我必须先审核自己的代码,看看我在对数组对象的赋值时是不是有遗漏,然后看看我在使用F先生的时候是不是有问题,再看看我在调用华夏接口的时候是不是有问题。

2. 尽量不要拆东墙,补西墙
这一点很重要,在证明自己的代码没有问题后,那么接下来怀疑的对象自然就是阿里巴巴提供的F先生,以及华夏银行提供的API接口。那么在这方面,我们经常容易冲动,因为好不容易抓住一下对方的把柄,我们还不乐呵一下。

我也犯错了!在证明自己的代码没有问题后,我开始怀疑F先生不支持数组对象的转换,因为F先生只提供了JSON.parseArray、JSON.parseObject两种方法(可笑我是多么的片面主义),经验主义告诉我,之前我们使用了这两种方法分别对List、Object对象进行转换,是没有问题的,但是对于华夏接口使用的Object []数组,F先生是不是不支持这种写法呢?

就如总结成功中所写的String [] schools字段,经过我的第一步测试,发现是支持的,那么既然支持数组,又为什么会丢失对象呢?

我开始怀疑是不是由于数据对象的三层关系,导致F先生无力转换呢?
Message msg = new Message();
  Student student = new Student();
  student.setName("lilei");
 
  String [] schools = new String[1];
  schools[0] = new String("21中");
 
  student.setSchools(schools);
 
  msg.setParamsObject("student",student);
 
  String json = JSON.toJSONString(msg);
  System.out.println(json);
  // {"code":0,"parames":{"student":{"name":"lilei","schools":["21中"]}}}

非常遗憾的是,我当时在测试这个步骤的时候,使用的是华夏提供的“非人类”的getxxx和setxxx方法(不是getXXX和setXXX)的对象,导致我并没有得出
{"code":0,"schools":["21中"]}}}
这个结论。

这个时候,同事说他通过jfinal提供的JsonKit(我记得好像是这个)对象可以转换华夏银行提供的“非人类”的getxxx和setxxx方法的对象,我也飘飘然的认为,这必须是F先生的一个bug(当时我还和同事一起嘲笑了阿里巴巴也不咋地,呵呵),于是乎,他提出了使用jackjson来替换fastjson的想法,并且实现了转换方法。

事情进展的似乎很顺利,我把项目中的fastjson抛弃了,换成了jackjson的两个jar包,并改换了对应的转换方法。

“月有阴晴圆缺”,等我草草的把重新打包后的jar包放到服务器上后,出现了一个惊人的错误,jackjson在把一个包含list的对象read为json的时候出现了错误(错误现在不记得了,等待周一的时候,我把错误补上),并且经历了很长时间,我和同事都没有能找到原因。已经快要下班了,由于要快速的实现华夏接口的对接,我决定不能再在这个问题上花费时间了,于是乎,我决定用我的方法解决问题。
Message msg = new Message();
  Student student = new Student();
  student.setName("lilei");
  School[] schools = new School[1];
  schools[0] = new School();
  schools[0].setName("21中");
  // student.setschools(schools);
  msg.setParamsObject("student",student);
  msg.setParamsObject("list",Arrays.asList(schools));
  String json = JSON.toJSONString(msg);
  System.out.println(json);
  // {"code":0,"parames":{"list":[{"name":"21中"}],"student":{"name":"lilei"}}}
  // 注意,由于Student对象中的setschools的缘故,我需要在message对象中加入list参数,专门传递School数组
  Message s = JSON.parseObject(json,Message.class);
  Student ss = JSON.parseObject(s.getParamsObject("student").toString(),Student.class);
  List<School> list = JSON.parseArray(s.getParamsObject("list").toString(),School.class);
  ss.setschools(list.toArray(new School[list.size()]));
  System.out.println(ss.getschools()[0].getName());
  // 21中
这种方式也是被华夏接口 逼迫的。


3. 翻看源码
显然,按照2中的方式解决了问题之后,一切就结束了吗?显然没有,如果你还记得总结中说的原因,那么接下来的工作就是找出原因。很巧合,在实际的开发过程中,我整理代码的时候,突然发现华夏接口在进行子账号签约工作时,也传递了数组对象,并且经过F先生转换后,数据时完全存在的,而为什么华夏接口的清算接口在转换过程中丢失呢?

幸好幸好,华夏接口API提供的jar包可以反编译。经过分析,我坚定的认为,问题就发生在华夏接口提供的类中,直接告诉我,肯定是数组对象的getter和setter方法写的有问题,经过同事的查看,的确,清算接口中使用了小写的getter和setter方法(再次强调,非人类,已经无力吐槽),而子账号签约却使用的大写写法(QNMD)。

翻看源码无疑是解决问题的杀手锏

相关文章

文章浏览阅读2.4k次。最近要优化cesium里的热力图效果,浏览...
文章浏览阅读1.2w次,点赞3次,收藏19次。在 Python中读取 j...
文章浏览阅读1.4k次。首字母缩略词 API 代表应用程序编程接口...
文章浏览阅读802次,点赞10次,收藏10次。解决一个JSON反序列...
文章浏览阅读882次。Unity Json和Xml的序列化和反序列化_uni...