有没有简便方法根据类型定制的json序列化的配置方式?

有没有简便方法根据类型定制的json序列化的配置方式?json对象,如果是Model或Record或Map集合

比如Model,或Record,如果内部有LocalDate,LocalDateTime,LocalTime三个时间类型的对象,要为这三个时间类型定制不同的日期格式化,而Json抽象类里只有一个setDatePattern。只能自己在内定义日期格式化,

我目前就想到一个方法,遍历Model,toJson方法内把所有的LocalDate,LocalDateTime,LocalTime转成字符串,但个方式这会改变Model的值,序列化后,可能之后Model还会使用。有什么好的方式么?而且Model对象内可能会有子对象,或子集合等,有什么简便的配置方法么?难道全部都要一个一个写出来?


各位有什么方法么?



评论区

杜福忠

2020-08-29 22:35

看帖了一天了还没人回复,不知道是大家和我一样没理解,还是续费情人节去了。。。后者可能多一点。。。要不再描述一下? 给个 jsonStr 字符串 或者贴贴码?
上面说会改变Model的值,如果字段有二次利用的情况,那可以使用 put 一个新字段,比如字段叫 date , 那么就model.put("dateStr", dateStr) 新加一个临时值进去

chilun555

2020-08-31 08:30

@杜福忠 另外还有嵌套情况,比如Map有List,List里有Map,里面都有java8日期对象,而且可能有两个不同类型的,例如LocalDate,LocalTime。把所有可能的情况都给考虑到if逻辑里去。

chilun555

2020-08-31 08:37

@杜福忠 jfinal自带的JfinalSON能不能像gson那样为某个类型单独配置一个序列化的方式么?

杜福忠

2020-08-31 10:14

/**
* 配置 ToJsonFactory,便于接管 ToJson 对象的创建
*
* <pre>
* 例子:
* JFinalJson.setToJsonFactory(value -> {
* if (value instanceof Model) {
* // 返回 MyModelToJson 接管对于 Model 类型的转换
* return new MyModelToJson();
* } else {
* // 返回 null 时将使用系统默认的转换类
* return null;
* }
* });
* </pre>
*/

chilun555

2020-08-31 13:59

@杜福忠 setToJsonFactory 这句话报错

chilun555

2020-08-31 14:00

@杜福忠 com.jfinal 4.8版本

杜福忠

2020-08-31 16:03

@chilun555 直接升级到4.9.01 没有一点问题,刚好重点就是JFinalJson的重构

chilun555

2020-09-01 09:17

@杜福忠 你发这个怎么用啊。我在if逻辑代码里里直接把返回值写成字符串常量都报错。反而是我找到的JFinalJson.addToJson可以,不过这个处理比较简单。虽然解决了,但是如果复杂一点,我要把某个自定义类型当成List进行序列化的这个要怎么操作(我自定义方法把自定义类型变成List,然后把List进行序列化)

杜福忠

2020-09-01 10:39

@chilun555 赞,用法差不多的,只是ToJson对象创建的时间不一样,Factory是用时才创建,不响应操作。 你说的 自定义类型当成List 是什么操作啊?有点没有明白,是类里面有个 List属性啊?还是继承了某List?

chilun555

2020-09-01 13:04

@杜福忠 好吧,我的表述有问题,那我换个说法,叫类型序列化拦截器把,比如我有个自定义类型,我要在序列化检测到该类型的时候,就进行拦截,拦截方法返回类型是Object类型,我随便在返回值里填什么。方法结束后,序列化的对象就会变成了由拦截器拦截后返回的对象了,序列化过程中,拦截所有在序列化中碰到的指定拦截类型。

假设我要对自定义类型进行拦截,在拦截方法里,直接创建一个List对象,并返回这个List对象。这样就实现了“自定义类型当成List进行序列化”。

杜福忠

2020-09-01 14:20

@chilun555 额,感觉越说越远了,还是说回 ToJson吧,我的理解就是把各对象的值转换为String就可以了,例子代码可以参考BeanToJson :
比如上面说的 要拦截某个方法,使用 Method 就能为所欲为了,
————————
前执行XXX
Object value = methods[i].invoke(bean, NULL_ARGS);
后执行XXX

chilun555

2020-09-01 14:41

@杜福忠 不好意思,你可能搞错了,我的意思是拦截指定类型的值,在拦截方法里,创建一个新对象,这个新对象可能跟拦截的对象不是一个类型,而且新对象不一定是String类型)。这个新对象就用作拦截方法的返回值。

举个例子把,比如Model,Record。JfinalJSon对这两个类型的对象序列化的效果跟序列化Map是一样的,也就是把Model,Record当成Map处理了(在序列化封装方法的某个过程获取内部包装的Map对象再进行序列化)。

假设有一个自定义类型的类,它的内部有一个集合,我想配置对该类的实例序列化为对内部的集合的序列化效果,把这个对象当成集合进行序列化(获取内部的集合再进行序列化)。就像JfinalJson对Model,Record的序列化效果一样

杜福忠

2020-09-01 14:51

@chilun555 抱歉我理解能力有点差,那模仿 ArrayToJson 了? 就像 处理Record一样,拿到 对象里面的那个 list集合,再 JFinalJsonKit.iteratorToJson(new ArrayIterator(object), depth, ret); 这样?

chilun555

2020-09-01 15:20

@杜福忠

那你能在详细示范一下么?我不太明白

chilun555

2020-09-01 15:26

@杜福忠 还有一个问题,如果自定义类型的内部不一定是集合,而是Map,Record,Model,Set,list,数组,自定义类型的任意一种,当序列化时,要当成Map/Record/Model/Set/List/数组/自定义类型(获取内部子对象在序列化)。

杜福忠

2020-09-01 15:32

@chilun555 我看别整那么麻烦了,自定义的类 直接符合 Bean规范就完事了,想获取啥样格式自己在类里面写 getXXX() 完事了,getMap/getRecord/getModel/getSet/getList/getArr/getXXX() ,哪怕对象只有一个属性,也可以建多个 get方法嘛

chilun555

2020-09-01 15:47

@杜福忠 你还不明白的话,那你看看这个问题帖子描述的问题吧 https://segmentfault.com/q/1010000023844864?_ea=62123639,虽然说的是用Gson如何实现。但如果换成Jfinal的json要如何处理?

杜福忠

2020-09-01 16:31

@chilun555 按照给的例子public class Test 意思这样写了:
ToJson<Test> toJson = (value, depth, ret) -> {
if (JFinalJsonKit.checkDepth(depth--, ret)) {
return ;
}
JFinalJsonKit.iteratorToJson(new ArrayIterator(value.getList()), depth, ret);
};
JFinalJson.addToJson(Test.class, toJson);

chilun555

2020-09-01 16:52

@杜福忠 如果把Test类的内部的那个集合换成Map、Set、数组、Jfinal的Record或Model、自定义类型的任意一个。

JFinalJsonKit.iteratorToJson(new ArrayIterator(value.getList()), depth, ret);这里的方法的第一个参数会有什么改动么?

杜福忠

2020-09-01 17:13

@chilun555 需要换的。 或者改成动态让它自己判断:
ToJson toJson = (value, depth, ret) -> {
Object object = value.getObject();
JFinalJsonKit.getToJson(object).toJson(object, depth, ret);
};
JFinalJson.addToJson(Test.class, toJson);

热门反馈

扫码入社