首页 > 编程知识 正文

类对象转成map,如何将json数据转化为对象

时间:2023-05-03 15:31:09 阅读:23188 作者:4636

对于大型企业APP应用程序,数据对象和映射可能需要相互转换。 通常,这是特殊序列化的中间步骤。 如果可以使用某些标准,则最好使用它们,但在许多情况下,根据一些最高配置修订者预期的体系结构、恶劣环境等,可以使用JOOQ、Hibernate、sdbb、JAX等。 就像那样。 在这种情况下,必须将对象转换为字符串或二进制文件的某种独特格式,如几年前遇到的那样。 朝着那个方向的第一步是将对象转换为Map。

最终,转换并不简单

映射mymap=(映射) myObject; 因为这些对象几乎不是自己的地图。 转换需要Map,每个条目都对应于" MyObject "类中的字段。 条目中的关键字是字段的名称,值是可能转换为Map本身的字段的实际值。

一种解决方案是使用反射以反射方式读取对象的字段,然后从中创建贴图。 另一种方法是在需要转换为Map的类中创建toMap )方法。 这只需要使用字段名将每个字段轻松添加到返回的Map中。 这比基于反射的解决方案更快,代码简单得多。

几年前,当我在实际的APP应用中遇到这个问题时,我对为每个数据对象创建原始的许多toMap ()方法感到沮丧,于是我创建了一个简单的基于反射的工具,可以对我们想要的任何类进行操作。 解决问题了吗? 没有。

这是一个专业的环境,这里不仅功能很重要,代码质量和程序员判断得出的我的代码质量也不一致。 他们认为基于反射的解决方案很复杂,一旦它成为代码库的一部分,以后加入常规开发人员也无法进行维护。 好吧,我必须承认它们是正确的。 在某些情况下,开发人员说他们必须在Java所需的水平上学习Java的反射和编程。 但在这种情况下,我们不是在谈论某个特定的人,将来,有人加入并加入团队,可能是我们离开项目某个地方的时候。 假设这个人是普通开发者,这似乎很合理,因为我们对这个人一无所知。 从这个意义上说,代码的质量很差。 因为太复杂了。 开发人员团队的法定人数决定,与将来寻找高级、有经验的开发人员相比,保留许多手动创建的toMap )方法更便宜。

老实说,我不想接受他们的决定,但即使光凭我在球队的地位就能推翻它,我也接受了。 即使我不同意,我也倾向于接受团队的决定,但前提是我能接受这些决定。 如果一个决定危险、可怕并且威胁到项目的未来,我们必须继续详细讨论,直到达成协议。

几年后,我开始创建Java : Geci作为副项目。 可从http://github.com/verhas/Java geci下载

Java : Geci是在Java开发生命周期测试阶段运行的代码生成工具。 Java : Geci中的代码生成是“测试”。 执行代码生成,如果剩下生成的所有代码,测试就会成功。 如果源代码发生更改,则测试将失败,因为代码库的内容发生更改,并且代码生成器生成的代码与以前不同。 如果测试失败,则必须更正错误并运行构建。 这包括重新运行测试。 在这种情况下,测试将生成新的、固定的代码,因此只需重新运行构建。

开发框架时,我创建了几个简单的生成器(equals () )和hashCode )、设置器和检索器以及生成器。 最后无法抵抗(通用到映射) )生成器。 此生成器生成的代码将对象转换为Map,如上所述。 另外,也有我没有事先提到的fromMap (),但很明显是必要的。

Java : Geci生成器是实现Generator接口的类。 映射器生成器可以扩展抽象类AbstractJavaGenerator。 这样,生成器就可以抛出任何异常,从而简化了生成器开发人员的工作,并且已经找到了从当前正在处理的源代码生成的Java类。 生成器可以通过参数klass访问实际的Class对象。 此外,还可以通过表示源代码并提供如何创建要插入的Java代码的参数source访问源代码。

第三个global参数类似于存储源代码注释@Geci中定义的配置参数的映射。

package javax0.geci.mapper; import . publicclassmapperextendsabstractjavagenerator { . @ overridepublicvoidprocess (源源源,类? klass,compoundparamsglobal (throws exception (finalvargid=global.get ) ' id ' ); varsegment=source.open(GID ); generatetomap (源、类、全局; generatefrommap (源、类、全局; 金融

var factory = global.get("factory", "new {{class}}()"); final var placeHolders = Map.of( "mnemonic", mnemonic(), "generatedBy", generatedAnnotation.getCanonicalName(), "class", klass.getSimpleName(), "factory", factory, "Map", "java.util.Map", "HashMap", "java.util.HashMap" ); final var rawContent = segment.getContent(); try { segment.setContent(Format.format(rawContent, placeHolders)); } catch (BadSyntax badSyntax) { throw new IOException(badSyntax); } }

生成器本身仅调用这两个方法generateToMap()和generateFromMap() ,这两个方法generateToMap() ,其名称暗示将toMap()和fromMap()方法引入类。

两种方法都使用Segment类提供的源生成支持,还使用Jamal提供的模板。 还需要注意的是,这些字段是通过调用反射工具方法getAllFieldsSorted()来收集的,该方法返回该类具有确定顺序的所有字段,而不依赖于实际的JVM供应商或版本。

private void generateToMap(Source source, Class<?> klass, CompoundParams global) throws Exception { final var fields = GeciReflectionTools.getAllFieldsSorted(klass); final var gid = global.get("id"); var segment = source.open(gid); segment.write_r(getResourceString("tomap.yydzxc")); for (final var field : fields) { final var local = GeciReflectionTools.getParameters(field, mnemonic()); final var params = new CompoundParams(local, global); final var filter = params.get("filter", DEFAULTS); if (Selector.compile(filter).match(field)) { final var name = field.getName(); if (hasToMap(field.getType())) { segment.write("map.put("%s", %s == null ? null : %s.toMap0(cache));", field2MapKey(name), name, name); } else { segment.write("map.put("%s",%s);", field2MapKey(name), name); } } } segment.write("return map;") ._l("}nn"); }

该代码仅选择由filter表达式表示的字段。

翻译自: https://www.javacodegeeks.com/2019/06/converting-objects-map-back.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。