长期以来,JSON已成为客户端和服务器之间各种数据序列化的事实上的标准。 除其他外,它的优势是简单和易于阅读。 但是,简单起了一些限制,我今天要谈的其中一个限制是:存储和检索多态Java对象。

让我们从一个简单的问题开始:过滤器的层次结构。 有一个抽象类AbstractFilter和两个子类RegexFilterStringMatchFilter

package bean.json.examples;public abstract class AbstractFilter {public abstract void filter();
}

这是RegexFilter类:

package bean.json.examples;public class RegexFilter extends AbstractFilter {private String pattern;public RegexFilter( final String pattern ) {this.pattern = pattern;}public void setPattern( final String pattern ) {this.pattern = pattern;}public String getPattern() {return pattern;}@Overridepublic void filter() {// Do some work here}
}

这是StringMatchFilter类:

package bean.json.examples;public class StringMatchFilter extends AbstractFilter {private String[] matches;private boolean caseInsensitive;public StringMatchFilter() {}public StringMatchFilter( final String[] matches, final boolean caseInsensitive ) {this.matches = matches;this.caseInsensitive = caseInsensitive;}public String[] getMatches() {return matches;}public void setCaseInsensitive( final boolean caseInsensitive ) {this.caseInsensitive = caseInsensitive;}public void setMatches( final String[] matches ) {this.matches = matches;}public boolean isCaseInsensitive() {return caseInsensitive;}@Overridepublic void filter() {// Do some work here}
}

没什么,纯Java Bean。 现在,如果我们需要将AbstractFilter实例的列表存储到JSON,更重要的是,要从JSON重新构造此列表,该怎么办? 以下类Filters演示了我的意思:

package bean.json.examples;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;public class Filters {private Collection< AbstractFilter > filters = new ArrayList< AbstractFilter >();public Filters() {}public Filters( final AbstractFilter ... filters ) {this.filters.addAll( Arrays.asList( filters ) );}public Collection< AbstractFilter > getFilters() {return filters;}public void setFilters( final Collection< AbstractFilter > filters ) {this.filters = filters;}
}

由于JSON是文本的,平台无关的格式,因此它不包含任何类型特定的信息。 得益于出色的Jackson JSON处理器,它可以轻松完成。 因此,让我们将Jackson JSON处理器添加到我们的POM文件中:

<project><modelversion>4.0.0</modelversion><groupid>bean.json</groupid><artifactid>examples</artifactid><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><project.build.sourceencoding>UTF-8</project.build.sourceencoding></properties><dependencies><dependency><groupid>org.codehaus.jackson</groupid><artifactid>jackson-mapper-asl</artifactid><version>1.9.6</version></dependency></dependencies></project>

完成此步骤后,我们需要告诉Jackson ,我们打算将类型信息与对象一起存储在JSON中,以便稍后可以从JSON重建确切的对象。 很少有AbstractFilter上的注释可以做到这一点。

import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonSubTypes.Type;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.annotate.JsonTypeInfo.Id;@JsonTypeInfo( use = Id.NAME )
@JsonSubTypes({@Type( name = "Regex", value = RegexFilter.class ),@Type( name = "StringMatch", value = StringMatchFilter.class )}
)
public abstract class AbstractFilter {// ...
}

而且...就是这样! 跟随帮助器类的工作是肮脏的工作,即将过滤器序列化为字符串,然后使用Jackson的 ObjectMapper从字符串反序列化它们:

package bean.json.examples;import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;import org.codehaus.jackson.map.ObjectMapper;public class FilterSerializer {private final ObjectMapper mapper = new ObjectMapper();public String serialize( final Filters filters ) {final StringWriter writer = new StringWriter();try {mapper.writeValue( writer, filters );return writer.toString();} catch( final IOException ex ) {throw new RuntimeException( ex.getMessage(), ex );} finally {try { writer.close(); } catch ( final IOException ex ) { /* Nothing to do here */ }}}public Filters deserialize( final String str ) {final StringReader reader = new StringReader( str );try {return mapper.readValue( reader, Filters.class );} catch( final IOException ex ) {throw new RuntimeException( ex.getMessage(), ex );} finally {reader.close();}}
}

让我们看看实际情况。 以下代码示例

final String json = new FilterSerializer().serialize(new Filters(new RegexFilter( "\\d+" ),new StringMatchFilter( new String[] { "String1", "String2" }, true ))
);

产生以下JSON:

{ "filters":[{"@type":"Regex","pattern":"\\d+"},{"@type":"StringMatch","matches":["String1","String2"],"caseInsensitive":true}]
}

如您所见, “ filters”集合中的每个条目都具有属性“ @type” ,该属性具有我们通过注释AbstractFilter类指定的值。 调用new FilterSerializer()。deserialize(json)会生成完全相同的Filters对象实例。

参考:我们的JCG合作伙伴 Andrey Redko在Andriy Redko {devmind}博客上提供了用于多态Java对象序列化的JSON 。

翻译自: https://www.javacodegeeks.com/2012/05/json-for-polymorphic-java-object.html

JSON用于多态Java对象序列化相关推荐

  1. Java对象序列化的本机C / C ++类似性能

    您是否曾经希望过像使用C ++这样的本地语言将Java对象转换成字节流一样快的速度? 如果您使用标准的Java序列化,您可能会对性能感到失望. Java序列化的目的是与尽可能快而紧凑地序列化对象的目的 ...

  2. java byte序列化,java对象序列化byte[] and byte[]反序列化对象--转

    import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOExceptio ...

  3. java 对象怎么序列化,java对象序列化总结

    java对象序列化小结 百度百科上介绍序列化是这样的: 序列化 (Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储 ...

  4. 关于 Java 对象序列化您不知道的 5 件事

    数年前,当和一个软件团队一起用 Java 语言编写一个应用程序时,我体会到比一般程序员多知道一点关于 Java 对象序列化的知识所带来的好处. 关于本系列 您觉得自己懂 Java 编程?事实上,大多数 ...

  5. Xson:Java对象序列化和反序列化工具

    1. Xson 介绍  Xson是一个Java对象序列化和反序列化程序.支持Java对象到字节数组的序列化,和从字节数组到Java对象的反序列化.  地址:https://github.com/xso ...

  6. java中将json字符串_Java中JSON字符串与java对象的互换实例详解

    在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JSON等,JSON作为一个轻量级的数据格式比xml效率要高,XML需要很多的标签,这无疑占据了网络流量,JSON在这方面则做的很好, ...

  7. 代码即财富之我学Java对象序列化与反序列化(2)

    2019独角兽企业重金招聘Python工程师标准>>> 我们在程序创建的Java对象都是存在于JVM内存中的,也就是Java对象的生命周期一定不会长于JVM,所以如何以一种持久化的方 ...

  8. JSON数据和Java对象的相互转换

    * JSON解析器:         * 常见的解析器:Jsonlib,Gson,fastjson,jackson          1. JSON转为Java对象         1. 导入jack ...

  9. 深入理解Java对象序列化

    关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...

最新文章

  1. [转帖]ASP.NET中常用的优化性能的方法
  2. 某医院DFT SCSI 300GB *8 RAID5数据恢复成功
  3. C++中的对象_纪要(二)
  4. python1到1000的质数_python求第1000个质数值的简单示例
  5. python判断是不是文件夹_Python判断文件和文件夹是否存在的方法
  6. wamp无法使用php,使用wamp无法访问www中的php文件
  7. double float区别 java,float和double有什么区别?
  8. elman神经网络_西瓜书第五章——神经网络
  9. 无法在计算机上读取移动硬盘,解决苹果电脑不能读写移动硬盘
  10. Another exception was thrown: The PrimaryScrollController is currently attached to more than one Scr
  11. Linux下安装sublime汉化版及完美输入中文
  12. w10计算机运行特别卡,win10更新后很卡怎么办_win10更新后电脑特别卡的解决方法...
  13. Android无线调试
  14. 关于STM32内部温度传感器的算式话题
  15. pe备份linux系统教程,如何使用老毛桃winpe的Bootice工具备份SYSLINUX引导程序?
  16. R语言caret机器学习(三):数据预处理下集
  17. 主流WiFi芯片原厂
  18. React学习笔记01: JSX 代码是如何“摇身一变”成为 DOM 的?
  19. python pdb 安装_Python调试工具pdb使用详解
  20. ForkJoin框架详解 一张图搞明白工作窃取(work-stealing)机制

热门文章

  1. dom4j-cookbook
  2. 公有云 私有云 混合云_混合云的承诺,收益和产品
  3. neo4j cypher_Neo4j:Cypher – Neo.ClientError.Statement.TypeError:不知道如何添加Double和String...
  4. 项目经理升职了是啥_什么是升职率?
  5. java 字段构造函数_依赖注入–字段vs构造函数vs方法
  6. openshift学习_在OpenShift上将JMS与JBoss A-MQ结合使用。 学习了有关远程客户端和加密的经验。...
  7. java 根据类名示例化类_如何使用示例从Java中的类路径加载资源
  8. JDK 14:CMS GC是OBE
  9. c++返回指针时候注意提防_编写干净的测试–提防魔术
  10. structure101_使用structure101分析软件包的依赖关系