我攻克的技术难题——我宣布Java Json不再需要定义实体类

发布于:2024-10-24 编辑:匿名 来源:网络

前言 之前有一篇文章讲了Java的Gson、FastJson等解析json的常用类。与Python的json模块相比,繁琐的部分是需要定义各种实体类。

那么,有没有一种方法可以在Java中自动定义实体类呢?数据访问是我的大数据工作的一部分。固定长度、csv 和 json 是一些更常见的数据格式。

通常我使用Flume来完成数据访问。我根据对端数据源配置源,在数据源上配置Interceptor,通道设置为kafka(一般是内存,所以放在kafka中进行流计算)。

Sink被设置为等待后续调度和存储的文件。 Flume提供的Source、Channel、Sink基本可以满足日常需求,并且可以通过conf配置轻松使用。

Interceptor往往需要自己开发封装,放在Flume的lib中,然后在conf配置中绑定到source,这样数据在进入通道之前就可以进行处理。随着访问的Json数据越来越多,每次访问json格式时,都必须定义一个实体类,然后定义一个Interceptor来将Json解析为CSV。

然后有一天我在想是否可以开发一个兼容Json的Interceptor。通过在配置文件中配置字段名,就会自动生成实体类,然后将实体类自动引入到Gson中解析json数据。

当javassist说到自动生成类时,让我想起了2006年自学Java时学到的javassist类。javassist提供了动态生成类的功能。

接下来我们看看如何使用javassist创建类。代码语言:xml copy org.javassist javassist 3.29.2-GA 由于CtClass是创建一个类,所以它必须会有一个类来表示正在构造的类对象,这样才能在类中添加字段和方法。

这个类就是CtClass,它是一个编译时类,编译时类文件。下一步是查看如何创建 CtClass 对象。

从注释来看,CtClass是从ClassPool中获取的。 ClassPoolClassPool是一个存储JVM加载的类的容器。

我们通常使用ClassPool.getDefault()来获取CLASSPATH类。代码语言:java copy ClassPool pool = ClassPool.getDefault();CtClass ctClass = pool.get("java.lang.String");System.out.println(ctClass);让我们获取 String 的 CtClass。

可以看到,String字段被封装成CtMethod类型,构造函数被封装成CTConstructor,同样的字段被封装成CtField。构建实体类下一步就是构建json数据对应的实体类。

通过调用CtPool的makeClass()方法,您可以创建一个新的空CtClass,然后添加字段和方法。 Flume主要是从外部配置参数,然后通过脚本启动,所以我通过参数配置json实体类的字段名。

日常开发中比较常见的json主要格式有两种:简单类型,每个字段对应一个简单类型。对于复杂类型,某些字段对应于自定义类数据或列表。

这里我们首先描述如何构建一个简单类型的实体类。制定规范,首先要根据要处理的数据定制规范。

代码语言:java Copy String json = "{\"name\": \"Tom\", \"age\": \"10\", \"time\": \"\" }";String className = "A";String fields = "name,age,time";String Connector = "|";代码中,json为要处理的json数据,className、fields、connector为传入的外部参数,分别是代表要创建的类。名称、字段和 toString 方法连接器。

构造ctClass 根据上面提到的方法,初始化ctClass后,需要添加字段和toString。代码语言:java copy public static CtClassgenerateClass(String className, String fields, String Connector) throws CannotCompileException { ClassPool pool = ClassPool.getDefault(); // 初始化 CtClas CtClass ctClass = pool.makeClass(className); for (String field: fields.split(",")) { // 添加字段 ctClass.addField(CtField.make("private String " + field + ";", ctClass)); } // 添加 toString 方法 ctClass.addMethod(CtMethod.make ("public String toString() { String result = " + fields.replace(",", "+ \"" + Connector + "\" +") + ";返回结果;}", ctClass)); return ctClass ;}通过ctClass.addField添加字段,参数类型为CtField,可以直接通过CtField.make构建。

拆分后,遍历传入的字段,将字段直接添加到ctClass中。这里我直接默认为String类型。

如果想做成其他类型,可以准确指定传入参数的数据类型。因为结果将以csv格式输出,所以必须在最后添加toString方法来定义输出格式。

您可以使用 addMethod 直接添加 toString 方法。连接器是每个字段的分隔符。

通过替换 fields.replace,将姓名、年龄和时间替换为姓名+“|” + 年龄 + “|” + time,用于构建 toString 代码。最后返回完成的ctClass。

loadClass以Gson为例。调用fromJson解析json字符串时,第一个参数是json字符串,第二个参数是Class对象。

如何通过CtClass获取Class,首先想到的肯定是类加载器ClassLoader。 Class源码注释中也提供了这个方法。

JVM使用ClassLoder.defineClass将编译后的类文件以字节形式加载并构建为Class对象。 Ctclass中的toBytecode可以将ctClass转换为class文件。

所以这里我们定义一个loadClass方法来生成Class。代码语言:java copy public static Class loadClass(CtClass ctClass, String className) { Class c = null;字节 [] 字节类;尝试 { byteClass = ctClass.toBytecode(); // 反射 Class clazz = Class.forName( "java.lang.ClassLoader");方法defineClass = clazz.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);定义Class.setAccessible(true); c = (Class ) DefineClass.invoke(ClassLoader.getSystemClassLoader(), className, byteClass, 0, byteClass.length); } catch (Exception e) { e.printStackTrace(); } return c;} 因为ClassLoder.defineClass是一个非公共方法,所以我们只能通过反射来调用这个方法,最终生成一个类对象。

这样Gson需要的Class参数也生成了,现在我们可以测试一下了。解析json来测试上面定义的json: 代码语言:java Copy String json = "{\"name\": \"Tom\", \"age\": \"10\", \"time\": \ "\" }";字符串类名 = "A";字符串字段 = "姓名、年龄、时间";字符串连接器 = "|";CtClass ctClass =generateClass(类名, 字段, 连接器);Gson gson = new Gson( ) ;Object o = gson.fromJson(json, loadClass(ctClass, className));System.out.println(o);结果输出:将json替换为其他字段进行测试: 代码语言:java Copy String json = "{ \" a\": \"11\", \"b\": \"10\", \"c\": \"22\", \"d\": \"22\"}";字符串类名 = "A";字符串字段 = "a,b,c,d,e";字符串连接器 = ",";CtClass ctClass =generateClass(类名, 字段, 连接器);Gson gson = new Gson();Object o = gson.fromJson(json, loadClass(ctClass, className));System.out.println(o);结果输出:经测试,可以实现简单类型json的配置解析。

结论关于复杂类型json解析和配置解析,也可以稍后再写。我在开发列表类型的json解析类时,使用javassist遇到了编译时的问题。

我稍后再研究。当然,我是2018年开始使用flume的,不仅仅是一些数据访问,还有大数据量的应用场景。

本人有使用flume从Kafka转HDFS超过1亿条记录/天(存储T/天)的实践,所以还是有一定经验的,对flume感兴趣的可以一起学习!我正在参加第五期腾讯科技创造特训营有奖征文比赛。

我攻克的技术难题——我宣布Java Json不再需要定义实体类

站长声明

版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。

标签:

相关文章

  • “家家泉”完成近亿元B轮融资,沣途资本领投

    “家家泉”完成近亿元B轮融资,沣途资本领投

    投资界(ID:pedaily)9月5日消息,水家电品牌“家家泉”(原“熊小夕”)已获完成近亿元人民币B轮融资,本轮融资由沣途资本领投,老股东纪源资本、天图资本跟投,木棉资本独家投资。 这是嘉泉成立两年来完成的第四轮融资。 据悉,本轮募集资金将主要用于嘉泉品牌建设以及新品

    06-17

  • 代码参与- “镭昱”成功点亮单芯片全彩芯片,助力AR眼镜革命性突破

    代码参与- “镭昱”成功点亮单芯片全彩芯片,助力AR眼镜革命性突破

    近日,镭昱宣布成功点亮了0.39英寸单芯片全彩Micro-LED micro-显示芯片,实现了产品标准化进程的突破性进展。 该芯片的成功点亮是Micro-LED单芯片全彩技术从概念到产品的重要里程碑,将为下一代消费类AR眼镜带来革命性的突破。 众所周知,单芯片全彩的实现是目前制约Micro-LE

    06-18

  • 金晟新能源完成数亿元B轮融资,复星锐领投

    金晟新能源完成数亿元B轮融资,复星锐领投

    投资圈(ID:pedaily)据8月15日消息,复星锐近日完成对广东金晟新能源有限公司的投资金晟新能源股份有限公司(以下简称“金晟新能源”)战略投资。 本轮投资由郑复星锐领投,国飞展信基金、广汽资本等机构跟投。 老股东中金资本、国民创投持续投资,投资金额数亿元。 作为一

    06-17

  • 小米成为第四季度俄罗斯线上销量最高的冠军品牌

    小米成为第四季度俄罗斯线上销量最高的冠军品牌

    Counterpoint Research发布的最新研究报告显示,小米已经超越三星和苹果,成为俄罗斯线上销量最高的手机品牌今年第四季度。

    06-18

  • 微博上市全景:如何打造另一个新浪?

    微博上市全景:如何打造另一个新浪?

    新浪微博(正式名称已更改为“微博”)北京时间昨晚,美国当地时间4月17日在纳斯达克正式挂牌上市。 微博董事长、曹国伟携手姚晨、王力宏等微博用户代表敲响纳斯达克开盘钟。   当天中午美股微博开盘后,股价立即快速上涨。 盘中一度上涨40%以上,市场买盘交投活跃。 微博首

    06-18

  • “分时悦动”获得CEiC

    “分时悦动”获得CEiC

    投资圈(ID:pedaily)数千万元Pre-A轮投资 据5月17日消息,金融数字化运营SaaS服务商北京分时悦动科技有限公司时光分享股份有限公司(以下简称“时光分享”)宣布完成数千万元Pre-A轮融资。 本轮融资由光大创新资本(以下简称“CEiC”)投资。 分时度假过往股东包括:红杉中

    06-17

  • 亲爱的创业者,你今天吃的是金拱门、陕北菜还是开封菜?

    亲爱的创业者,你今天吃的是金拱门、陕北菜还是开封菜?

    又到周五了,美丽大方、俏皮可爱、拥有1.5米大长腿的本雅又登场了!周末正是敞开肚皮大吃大喝的时候。 想在这个美丽的周末少年吃一顿中国最传统的“金拱门”吗?是的,你我都知道麦当劳正在流行。 麦当劳(中国)有限公司于10月12日更名为金拱门(中国)有限公司。 麦当劳首席

    06-18

  • 远洋集团今年前两个月合约销售额突破100亿,同比增长53.68%

    远洋集团今年前两个月合约销售额突破100亿,同比增长53.68%

    远洋集团(7.HK)昨日公布,1-2月累计合约销售额2月份已达到约2000万元人民币。 元,累计合同销售面积约55.6万平方米,今年2月合同销售额约45.2亿元。 听,中小企业反馈平台。 倾听用户需求,倾听创业者声音,解决中小企业痛点。 点击立即参与调查并获得礼物。

    06-17

  • 去深圳吧!创马10位评委导师阵容抢先看!

    去深圳吧!创马10位评委导师阵容抢先看!

    距离全球创客马拉松两周年大赛还有不到十天,赛事主办方哈德创邦的合作伙伴也在积极做最后的准备。 今天小编赶紧去获取信息。 据悉,今天,公司已经确定了本次大赛的评委和导师阵容。 听说还有重量级人物担任评委。 来看看具体权重吧~ 大赛评委封昌红,澳门科技大学MBA,中共

    06-17

  • 智能家居伴侣!乐橙小乐经验回顾

    智能家居伴侣!乐橙小乐经验回顾

    由于国内二胎政策的放开,很多家庭的宝宝数量也开始增加。 国家卫生计生委表示,二胎政策放开后,短期内我国出生人口将大幅增加。 到了这一年,大约有 10,000 人出生。 目前,一些厂商聚焦婴幼儿市场,推出了一些针对婴幼儿的智能产品。 主要是儿童手表和儿童机器人。 今天我

    06-18

  • 超过110亿元!北汽新能源汽车创下行业最大单笔融资,为何全部退出……

    超过110亿元!北汽新能源汽车创下行业最大单笔融资,为何全部退出……

    过亿的融资金额对于新能源来说算大吗?    据投资界8月14日消息,北汽新能源今日正式宣布,公司已完成总额1800万元B轮融资,中国信达、中基投资、兴旺产业园、国轩投资共14家投资者参与了本轮融资。   创下新能源汽车行业单笔最大融资纪录,并已在筹备IPO。    据了解

    06-18

  • 59岁的物美创始人即将拥有两家上市公司

    59岁的物美创始人即将拥有两家上市公司

    难得一见的张文中悄然变身IPO收割机。 投资界天天IPO(ID:pedailyIPO)获悉,物美科技已正式向港交所提交上市申请。 此次,物美超市与麦德龙中国计划将产品一起打包上市。 招股书显示,物美科技营业收入达1亿元。 而物美科技背后站着的是曾经称霸商界的张文中。 他的人生经历

    06-18