JSON用于多态Java对象序列化

长期以来,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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 命令分类,常用linux 命令分类整理(篇一)

工作中接触linux时间也不算短了&#xff0c;不同于Windows的图形化操作&#xff0c;使用linux几乎百分之九十五的情况是在命令行下过日子&#xff0c;过去的两年里&#xff0c;零零碎碎整理过一版自己工作中涉及到和学习过的命令(不过常用的只有三十个左右)&#xff0c;思前想后…

考研复习策略

考研复习是一个不容易的过程&#xff0c;有好的策略事半功倍&#xff0c;以我曾经失败的教训和成功的实践给出了我认为不错的策略&#xff0c;只要能做到&#xff0c;我相信一定能考研成功。 院校选择&#xff1a;985院校在选择考研院校是有优势的&#xff0c;院校考虑的因素有…

js中的this指针(二)

在 js 中声明并定义一个函数后&#xff0c;除了定义时传入的形式参数&#xff0c;函数还会接收到 2 个附加的参数&#xff1a;this 和 arguments。 this 指针的值取决于调用时的模式。 当这个函数被保存为对象的一个属性时&#xff0c;它被称为“方法”。当一个方法被调用时&am…

使用AspectJ和Spring简化了AOP

我最近开始研究面向方面的编程&#xff08;AOP&#xff09;&#xff0c;至少可以说使我兴奋。 当然我很熟悉它&#xff0c;因为我看到它在Spring中用于事务管理&#xff0c;但是我从未深入研究它。 在本文中&#xff0c;我想展示通过AspectJ可以快速掌握AOP和Spring。 本文中的…

第一冲刺阶段 工作总结 04

1、昨天我继续我的任务&#xff0c;连接数据库。 2、今天打算继续做数据库的连接。 3、遇到的问题&#xff1a;昨天在数据库连接时&#xff0c;老是连接不上&#xff0c;显示错误&#xff0c;所以今天打算接着弄。转载于:https://www.cnblogs.com/zz0906/p/5422510.html

windows2012同步linux时间,Windows server2012时间同步NTP配置

遇到经常服务器时间无法同步&#xff0c;可以自己建立一台时间同步服务器&#xff0c;NTP配置如下&#xff1a;一、服务端配置 (Ntp服务器&#xff0c;客户端将根据这台服务器的时间进行同步)1、微软键R键&#xff0c;进入“运行”&#xff0c;输入“regedit”,进入注册表2、 H…

反差萌

反差萌 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 0 Accepted Submission(s): 0 Problem Description有2N个人&#xff0c;每人有个萌值Mi(1<i<2N)。 要求将他们分为N对&#xff0c;使得反差值之和…

Java EE 6示例– Galleria第2部分

您可能在最后一篇Java EE 6 Galleria示例帖子中关注了我。 第一个是基本介绍。 第二个是关于在最新的GlassFish上运行它。 有人提到RedHat&#xff0c;我们应该研究将这个示例从GlassFish中移除。 很好;&#xff09;感谢您的好主意。 这正是我们今天要做的。 我将把Galleria示例…

suggest

http://lovebeyond.iteye.com/blog/941633转载于:https://www.cnblogs.com/sunxun/p/5421251.html

linux的tar命令压缩26g文件,linux如何使用tar命令大包压缩进文件

linux如何使用tar命令大包压缩进文件发布时间&#xff1a;2020-05-29 12:30:14来源&#xff1a;亿速云阅读&#xff1a;206作者&#xff1a;Leah本篇文章主要介绍linux中使用tar命令大包压缩进文件的方法。内容比较详细&#xff0c;文章包含了命令的使用示例&#xff0c;希望大…

与reCAPTCHA的Spring集成

有时我们只需要CAPTCHA &#xff0c;这是一个可悲的事实。 今天&#xff0c;我们将学习如何与reCAPTCHA集成。 因为主题本身并不是特别有趣和高级&#xff0c;所以我们将通过使用Spring Integration处理低级细节来过度设计&#xff08;&#xff1f;&#xff09;。 Google决定使…

《机器学习基石》---感知机算法

1 推导感知机模型 基本思想是&#xff0c;把特征的线性加权值作为一个分数&#xff0c;根据这个分数与一个门限值的关系来进行分类&#xff1a; 我们加一个特征x0等于1&#xff0c;门限值就可以放到w里面去&#xff0c;得到更简单的形式&#xff1a; 这就是感知机模型&#xff…

未知错误:1000正在终止线程

若在try{} catch{}的catch 块中加入 catch (Exception ex) { Response.Write(ex.Message); Response.End(); } 则捕获异常后&#xff0c;提示未知错误&#xff1a;1000正在终止线程 转载于:https://www.cnblogs.com/dennysong/p/5422567.…

分叉并加入Java 7 – JSR 166并发实用程序

Java 7最有趣的改进之一是对并发的更好支持。 使用JSR 166并发实用程序&#xff0c;我们可以对并发进行一些非常有用的改进。 在我看来&#xff0c;fork-join库在软件工程中具有很高的实际应用潜力。 Fork and join为算法提供了非常简单的编程模型&#xff0c;可以将其实现为递…

linux内核源码代码量,Linux内核源代码数量已经超过1000万行

Linux版本2.6.27更新后,人们发现,这一内核的源代码数量已经超过了1000万行.当然,这些行数仅仅是计算机统计出来的行数,包括空白行,为了代码的可读性增加的注释等,当然Linux和所有的长期项目一样,随着时间的推移,旧的代码 会被丢弃和更换,但总体规模来说,Linux的内核在不断增强,…

Python之路【第八篇】:堡垒机实例以及数据库操作

Python之路【第八篇】&#xff1a;堡垒机实例以及数据库操作 堡垒机前戏 开发堡垒机之前&#xff0c;先来学习Python的paramiko模块&#xff0c;该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接&#xff1a; 12…

关于typedef的使用方法

在计算机编程语言中用来为复杂的声明定义简单的别名。与宏定义有些差异。它本身是一种存储类的keyword&#xff0c;与auto、extern、mutable、static、register等keyword不能出如今同一个表达式中。typedef声明&#xff0c;简称typedef&#xff0c;为现有类型创建一个新的名字&…

ADF BC:创建绑定到业务组件的UI表

在此示例中&#xff0c;我们将展示如何创建绑定到业务组件的简单UI表&#xff08;af&#xff1a;table&#xff09;。 我再次尝试使用简单的标准在网上进行搜索&#xff1a; “如何创建绑定到业务组件ADF 11g的af&#xff1a;table” 我必须承认我没有得到我想要的答案。 信息…

linux驱动程序混合架构,嵌入式系统最小驱动框架(类似linux驱动程序架构)(示例代码)...

2010年就打算把linux里的驱动框架核心代码抠出来的&#xff0c;但是由于懒而且linux代码量大&#xff0c;一直下不了手。最近调试的intel curie里驱动架构也类似linux&#xff0c;代码就少多了&#xff0c;由于工作需要不得不梳理一下这一堆代码&#xff0c;今天花了一下午&…

MyBaits 错误分析

错误原因&#xff1a;在DAO的映射文件中&#xff0c;在映射标签中的type类型写成DAO类了&#xff0c;应该写成javaBean转载于:https://www.cnblogs.com/shuaiandjun/p/5428847.html