阿里fastjson使用笔记,parseObject问题,输出下划线格式,json格式化等,不打印base64等 文章目录maven引入JSONField首字母大写的序列化默认驼峰自动序列化拓展: JSON.parseObject一个空对象会报错吗?如果是Resource资源使用Json序列化容易有问题parseObject遇到的问题输出下划线格式json打印设置输出空字符串参数含义CustomJsonUtilsfastjson2其他controller初始化的时候可以设置本类的json接收?(待办)不打印base64file等为什么有的类打印时不用JSON.toJSONString()报错 JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT tokenorg.json报错 java.lang.NoSuchMethodError: org.json.JSONObject.init(Ljava/lang/Object;)Vjson工具中fastjson是主流中的一种。maven引入pom.xml中添加dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.58/version/dependency代码publicclassJsonTest{publicstaticvoidmain(String[]args){MapInteger,ObjectmapnewHashMapInteger,Object();ArrayListPersonlistnewArrayListPerson();PersonpersonnewJsonTest().newPerson();Personperson2newJsonTest().newPerson();person.setName(张飞);person.setAge(28);person2.setName(guanyu);person2.setAge(30);list.add(person);list.add(person2);map.put(1,String1);map.put(2,String2);map.put(3,list);StringjsonStringJSON.toJSONString(map);System.out.println(jsonString);JSONObjectjsonObjectJSON.parseObject(jsonString);Stringstring1jsonObject.getString(1);Stringstring2jsonObject.getString(2);JSONArraylist1jsonObject.getJSONArray(3);System.out.println(list1);System.out.println(list1.get(0));}classPerson{privateStringname;privateStringage;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicStringgetAge(){returnage;}publicvoidsetAge(Stringage){this.ageage;}}}**对象 jsonString **JSON.toJSONString(map);**jsonString obj **JSON.parseObject(jsonString);当然也可以转换为某个类的对象代码DataEntitypublicclassPerson{privatestaticfinalLoggerloggerLoggerFactory.getLogger(Person.class);IdprivateLongid;privateStringname;publicstaticvoidmain(String[]args){PersonpersonnewPerson();person.setId(159L);person.setName(chushiyun);StringsJSON.toJSONString(person);logger.info(json 字符串是{},s);Personperson1JSON.parseObject(s,Person.class);logger.info(person1.toString());}}JSONField如果字段有不一致的时候那么可以加JSONField注解,序列化和解析的时候就会按照这个字段来解析如代码DataEntitypublicclassPersonManage{IdprivateLongid;JSONField(namename)privateStringmanageName;}首字母大写的序列化有历史需求很变态报文首字母大写。找不准到底是哪种json解析器简单点就直接首字母改为大写也直接可以序列化了。默认驼峰自动序列化可以不加注解吗?可以如果属性命名是驼峰形式且完全匹配那么不加注解也能序列化成功。拓展: JSON.parseObject一个空对象会报错吗?好问题一起来看一下。JSON.parseObject一个空对象会报错吗?(null);不会。但是要注意返回的是个null对象如果继续调用方法会报错。用代码验证下// 这句不会报错JSONObjectjsonObjectJSON.parseObject(null);// 这句会报错// 因为之前返回的JsonObject是null调用任何方法都会报错StringstringjsonObject.getString(username);如果是Resource资源使用Json序列化容易有问题序列化之后发现文件变成非正常文件了。代码PathpathPaths.get(d:\\,filename);ResourceresourceresourceLoader.getResource(file:path.toString());logger.info(resource{},JSON.toJSONString(resource));// 都是这句json惹的祸页面输出不了目前还不知道原理总之在序列化Resource资源的时候要小心。parseObject遇到的问题解析复杂对象的时候直接使用parseObject会有问题要用这种解析方式JsonResultMultiModelredisJsonResultJSON.parseObject(jsonString,newTypeReferenceJsonResultMultiModel(){});输出下划线格式标准产品是下划线格式日志也打印为下划线格式直接就能复用否则还需要转您换。publicstaticvoidmain(String[]args){SerializeConfigserializeConfignewSerializeConfig();serializeConfig.propertyNamingStrategyPropertyNamingStrategy.SnakeCase;UserusernewUser();user.setUsername(asdfad);log.info(JSON.toJSONString(user,serializeConfig));}发现果然是下划线格式了。json打印设置输出空字符串默认是不打印空字符串的但是有时需要打印例如写接口文档打印出来空值比较方便。代码SerializeConfigconfignewSerializeConfig();UserRequestrequestnewUserRequest();StringcontentJSON.toJSONString(request,config,SerializerFeature.WriteNullNumberAsZero,SerializerFeature.WriteNullListAsEmpty,SerializerFeature.WriteNullStringAsEmpty,SerializerFeature.WriteNullBooleanAsFalse);log.info(content);那么list呢?实际如果list为空即使做了如上设置也是打印不出来的。解决方案1、list中添加一个有值对象。实际上写接口文档时list中的类单独打印出来也是可以的。参数含义// 定义一套针对 null 值的默认值序列化特性// 1. WriteNullNumberAsZero: 当数字类型如 Integer, Long, Double为 null 时强制输出为 0// 2. WriteNullListAsEmpty: 当集合类型如 List, Set为 null 时强制输出为 []空数组// 3. WriteNullStringAsEmpty: 当字符串类型String为 null 时强制输出为 空字符串// 4. WriteNullBooleanAsFalse: 当布尔类型Boolean为 null 时强制输出为 falseprivatestaticfinalSerializerFeature[]NULL_DEFAULT_FEATURES{SerializerFeature.WriteNullNumberAsZero,SerializerFeature.WriteNullListAsEmpty,SerializerFeature.WriteNullStringAsEmpty,SerializerFeature.WriteNullBooleanAsFalse};CustomJsonUtilspublicclassCustomJsonUtils{// 定义一套标准的序列化特性全局统一使用// 1. WriteNonStringKeyAsString: 强制把非字符串的 Key如 Long转成带双引号的字符串// 2. WriteMapNullValue: 如果值为 null也保留该字段输出 key:null而不是直接忽略// 3. DisableCircularReferenceDetect: 关闭循环引用检测防止出现 $ref 这种奇怪的符号privatestaticfinalSerializerFeature[]FEATURES{SerializerFeature.WriteNonStringKeyAsString,SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect};publicstaticStringtoJsonString(Objectobject){StringsJSON.toJSONString(object,FEATURES);returns;}}fastjson2对比fastjson性能更快安全性更高推荐使用。其他controller初始化的时候可以设置本类的json接收?(待办)不打印base64file等base64太长打印非常影响查日志而且没什么实际意义。file则是不好打印。所以打印日志时最好去掉这两种。json自带这种机制配置下即可。代码是网上通用的代码publicstaticSimplePropertyPreFilterfilePropertyPreFilternull;static{filePropertyPreFilternewSimplePropertyPreFilter();filePropertyPreFilter.getExcludes().add(file);filePropertyPreFilter.getExcludes().add(base64String);}JSON.toJSONString(request,CustomJsonUtils.filePropertyPreFilter);这里是根据属性名进行过滤。为什么有的类打印时不用JSON.toJSONString()很简单继承一个类抽象类。重写toString()方法return JSON.toJSONString(this);报错 JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token报错信息为JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token问题原因这是因为 userList 是个list报文写错了用的大括号。其实应该是 []。org.json报错 java.lang.NoSuchMethodError: org.json.JSONObject.(Ljava/lang/Object;)V刚看到了也是一脸蒙本地调试是可以的。1、版本不对。2、构造器不支持。即 虽然对象为Object但是实际只支持几种固定的入参类型。// 正确使用方式JSONObjectobj1newJSONObject({\key\:\value\});// StringJSONObjectobj2newJSONObject(newHashMapString,Object());// MapJSONObjectobj3newJSONObject();// 无参构造// 可能导致问题的调用某些版本不支持ObjectsomeObjectgetObject();JSONObjectobjnewJSONObject(someObject);// 可能不存在实测确实如此例如可以接收json字符串但是传了个jsonObject就会报如上错误。扩展一下如果传的是个数组格式的json字符串但是用jsonObject封装的也会报错。总之org.json是个轻量级的json简便但是用起来比较容易报错。

本月热点