首页 > 其他分享 >FastJson序列化和反序列化问题记录

FastJson序列化和反序列化问题记录

时间:2022-10-30 10:03:00浏览次数:61  
标签:FastJson JSONField String 记录 default private 序列化 name


序列化与反序列化问题

调用外部接口,http://100.111.55.67:9999/cmdb/v0.2.0/departments?page_size=1000,返回数据格式如下:

{
"code": 0,
"content": [
{
"id": "4561",
"level": 1,
"name": "业务后台",
"parent_id": "1",
"parent_name": "信仰科技"
}
],
"msg": "success"
}

居然是下划线命名的。现在需要将该接口包一层,然后暴露给前端。前后端的开发规范是返回驼峰命名的数据。

直接使用JSONObject解析也行,但是较好的方式是定义一个POJO,并加上注解​​@JSONField​​:

@Data
public class CmdbModel {
private Integer id;
private Integer level;
private String name;
@JSONField(name = "parent_id")
private Integer parentId;
@JSONField(name = "parent_name")
private String parentName;
}
@Data
private static class Resp {
private Integer code;
private List<CmdbModel> content;
private String msg;
}

Service层代码就是一个简单的HTTP Get,然后JSONObject反序列化解析定义的POJO class类。

@Override
public List<CmdbModel> listDepartment() {
String url = cmdbUrl + DEPARTMENTS;
try {
Resp resp = JSONObject.parseObject(HttpUtil.doGet(url), Resp.class);
if (resp != null && resp.getCode() == 0) {
return resp.getContent();
}
} catch (Exception e) {
log.error("listDepartment failed: ", e);
}
return Collections.emptyList();
}

此处返回的数据肯定就是驼峰命名的。

Controller层接口

@RequestMapping("listDepartment")
public String listDepartment() {
return JSONObject.toJSONString(ServiceUtil.returnSuccessData(cmdbService.listDepartment()));
}

问题:Postman调用此接口,发现数据居然和最原始的外部接口的数据一样,是下划线命名。

使用的依赖及其版本号:

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>

原因:​​ServiceUtil.returnSuccessData​​​返回的是​​Map<String, Object>​​​类型的数据,​​JSONObject.toJSONString​​​将Map序列化时,发现有​​@JSONField​​注解,然后又把驼峰命名转换为下划线命名。

能不能从​​@JSONField​​注解入手解决问题?

看看​​@JSONField​​源码:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface JSONField {
int ordinal() default 0;

String name() default "";

String format() default "";

boolean serialize() default true;

boolean deserialize() default true;

SerializerFeature[] serialzeFeatures() default {};

Feature[] parseFeatures() default {};

String label() default "";

boolean jsonDirect() default false;

Class<?> serializeUsing() default Void.class;

Class<?> deserializeUsing() default Void.class;

String[] alternateNames() default {};

boolean unwrapped() default false;

String defaultValue() default "";
}

期望效果:反序列化时把下划线反序列化为驼峰命名,随后返回前端的String需要经过一次序列化过程,序列化时保留驼峰命名。

实验:
注解加上​​​serialize​​​配置得到:​​@JSONField(name = "parent_id", serialize = false)​​,直接忽视此字段。

看样子,无法从此注解入手解决问题???

另外,不知道另外一个据说比fastjson更强大,版本发布频率强力碾压fastjson的JSON工具jackson,怎么解决这个"问题"?

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>

解决方法:再定义一个VO,CmdbVo的字段和CmdbModel的字段一模一样,只是没有​​@JSONField​​​注解,然后使用​​BeanUtils​​进行数据赋值:

List<CmdbVo> cmdbVoList = Lists.newArrayListWithCapacity(resp.getContent().size());
resp.getContent().forEach(x -> {
CmdbVo vo = new CmdbVo();
BeanUtils.copyProperties(x, vo);
cmdbVoList.add(vo);
});


标签:FastJson,JSONField,String,记录,default,private,序列化,name
From: https://blog.51cto.com/u_15851118/5807201

相关文章

  • TypeScript第一天学习记录
    2022年10月29日19点17分1.TypeScript是什么1.1TypeScript是什么?TypeScript(简称:TS)是JavaScript的超集(JS有的TS都有)TypeScript=Type+Javascript(在JS基础之上,为J......
  • 记录一次redis分布式锁的坑
    redis分布式锁的实现方式是:lock(){sync(this){//无法获取自旋setnx(key,UUID)setex(60s)returnUUID}}unlock......
  • Serialzable和Parcelable的区别?Bunder传递对象为什么需要序列化?
    1Bunder传递对象为什么需要序列化?因为bundle传递数据时只支持基本数据类型,所以在传递对象时需要序列化转换成可存储或可传输的本质状态(字节流)。序列化后的对象可以在网络、......
  • 个人算法学习记录
    个人算法学习记录暑假准备夏令营的时候学习了一些算法,并作了记录。想法是学完所有内容,然后记录下来,然而想法是美好的,实际上只学到了动态规划那一章,并且只记录了最简单的几......
  • 使用python 接入LDAP验证系统实践记录
    LDAP简介LDAP(LightDirectoryAccessPortocol)是轻量目录访问协议,基于X.500标准,支持TCP/IP。LDAP基本概念LDAP的目的是为各种软件提供统一标准的认证机制,所有软件就可......
  • 阿里云的RDS 使用 记录
     --线上产品抱错如下:TheMySQLserverisrunningwiththeLOCK_WRITE_GROWTHoptionsoitcannotexecutethisstatement 看起来是锁了,原因是RDS满了,阿里云看起来......
  • 记录第一次使用c++和汇编联合编译
    32位从Ida把目标函数扣出来toUapperprocneararg_0=dwordptr4pushesimovesi,[......
  • wpf .net core win7 独立运行补丁安装记录
     Windows7系统上,根据dotnet官方文档,需要安装上KB2533623补丁方案如下:首先使用 fx2.0 写一个启动器 如果检测可以运行则拉起.net core 主程序 否则弹出命令......
  • 运用索引快速删除aud$表6个月前的审计记录
    文档课题:运用索引快速删除aud$表6个月前的审计记录.应用场景:最近在生产库发现定时Job执行删除aud$表6个月前的记录需要1.5小时,该表大小30g,总记录数0.12billion.真是有点耗......
  • 记录坑:根据四个特征点估计相机位姿
    坑1:不是所有的C++都是ubuntu下的linux运行的,也可以使用windows下的visualstudio来运行。坑2:opencv环境配置?由于涉及到opencv,因此先去官网进行了下载,具体安装步骤见......