Java:关于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,"parames":{"student":{"name":"lilei","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)。

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

3.翻看源码

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

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

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

时间: 2024-10-08 16:05:42

Java:关于fastjson先生的一段插曲的相关文章

java linux ImageIO 验证码在一段时间以后出不来 问题总结

最近在测试上布署的项目经常性的出现验证码过了一段时间以后出不来的情况,耐心找了一下,最后在上级的指导下发现了报错,其实说真的,我自己也找到了这个报错,只是没有当一回事.因为这个验证码的东西不是我写的,我也不知道这个报错是不是和它有关系. 错误如下: 2014-05-21 10:46:17,826 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Could not complete request org.springfram

java, listmap2json, fastjson

import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; import com.alibaba.fastjson.JSON; public class ListMap2Json {     /**     * @param Lavender     */    public static void main(String[] args) {      /*  Ma

java 限定网站在指定IP段访问

贴代码 IpUtil.java package com.datongsoft.wg.common.util; import java.net.InetAddress; import java.net.UnknownHostException; public class IpUtil { /*验证IP是否属于某个IP段 * * ipSection IP段(以'-'分隔) * ip 所验证的IP号码 * */ public static boolean ipExistsInRange(String

java alibaba fastJson 遍历数组json

import java.util.*; import com.alibaba.fastjson.*; public class Test { public static void main(String[] args) { //方法1 String json = "[{\"companyId\":\"111111111\",\"companyName\":\"Huuuu\",\"_uid\":10

前言 致Java开发学习前的一段话

学习编程到底难不难?学习java到底难不难?编程就是会者不难,难者不会的事情:所以,不要再无谓的去问别人学习编程难或不难的问题,因为不管这个答案是什么,都可能不是你想要的.那么,我们需要做的就是坚持和自信,相信自己能够学得会. 你只要在一个方向里,努力学习钻研十年,那你至少能成为这个行业的一个专家. Java学习方法:多敲.多问.多记! 有一种生活,你没有经历就不会知道其中的艰辛:有一种艰辛,你没有体会过就不会知道其中的快乐:有一种快乐,你没有拥有就不能知道其中的纯粹. 0.1 Java SE基

Android java判断字符串包含某个字符段(或替换)

String str = "1234567"; if(str.indexOf("23") != -1) { System.out.println("包含该字符串"); }

kuangerren[shijing266推荐] java网站,tomcat运行一段时间后会自...[Web ]

5究汾7滓肪1涯遮v侥称http://blog.sina.com.cn/s/blog_17bb988440102y8bg.htmly檬人4酶伟q敢奈2悔芽http://blog.sina.com.cn/s/blog_17b64aa860102wwe2.htmlh捞沧r儋靥5懦棺7酶撑http://blog.sina.com.cn/s/blog_17bbaf20f0102xzra.htmla姓杆w刃潮4低喂i堑攀http://blog.sina.com.cn/s/blog_17bb19f12010

Java利用FastJson一行代码转List&lt;Map&gt;为List&lt;Bean&gt;

/** * 字符串 -> json对象.实体对象.Map.List.List<Map> */ // 字符串 -> json对象 JSONObject json = JSON.parseObject(string); // 字符串 -> 实体对象 User user = JSON.parseObject(string, User.class); // 字符串 -> Map Map<Object, Object> map = JSON.parseObject(s

fastJson java后台转换json格式数据

什么事JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等