自定义jackson序列化

tl; dr:将输入验证添加到Jackson中的自定义json解串器中很重要。

在RHQ中,我们在几个地方使用了Json解析-直接在as7 / Wildfly插件中,或者通过RESTEasy 2.3.5间接在REST-api中使用,已经很繁重了。

现在,我们有一个bean Link ,看起来像:

public class Link {String rel;String href;
}

序列化的标准方法是

{ "rel":"edit", "href":"http://acme.org" }

由于我们需要其他格式,因此我编写了一个自定义序列化程序并将其附加在类上。

@JsonSerialize(using = LinkSerializer.class)
@JsonDeserialize(using = LinkDeserializer.class)
@Produces({"application/json","application/xml"})
public class Link {private String rel;private String href;

此自定义格式如下:

{"edit": {"href": "http://acme.org"}
}

由于客户端也可以发送链接,因此需要进行一些自定义反序列化。 解串器的第一个片段看起来像这样,效果很好:

public class LinkDeserializer extends JsonDeserializer>{@Overridepublic Link deserialize(JsonParser jp,DeserializationContext ctxt) throws IOException{String tmp = jp.getText(); // {jp.nextToken(); // skip over { to the relString rel = jp.getText();jp.nextToken(); // skip over  {[…]Link link = new Link(rel,href);return link;}

现在,几天前发生的事情是,在某些测试中,我正在发送数据,而我们的服务器严重崩溃。 内存使用量增加,垃圾回收器花费了大量cpu时间,并且该调用最终因OutOfMemoryException终止。

经过一番调查,我发现客户端没有以我们的特殊格式发送Link对象,而是以我最初显示的原始格式发送了。 进一步的研究表明,实际上, LinkDeserializer正在消耗流中的令牌,如上所示,然后还吞没了输入中的后续令牌。 因此,当它返回时,整个解析器的状态很差,然后尝试复制大数组,直到我们看到OOME。

得到这个之后,我更改了实现以添加验证并在无效输入时尽早提供援助,以使解析器在无效输入时不会陷入不良状态:

public Link deserialize(JsonParser jp,DeserializationContext ctxt) throws IOException{String tmp = jp.getText(); // {validate(jp, tmp,"{");jp.nextToken(); // skip over { to the relString rel = jp.getText();validateText(jp, rel);jp.nextToken(); // skip over  {tmp = jp.getText();validate(jp, tmp,"{");[…]

然后,那些validate*()简单地将令牌与传递的期望值进行比较,并对意外输入抛出Exception:

private void validate(JsonParser jsonParser, String input,String expected) throws JsonProcessingException {if (!input.equals(expected)) {throw new JsonParseException("Unexpected token: " + input,jsonParser.getTokenLocation());}}

验证也许可以进一步改善,但是您可以理解。

参考: Jackson中的Custom Deserializer,以及 JCG合作伙伴 Heiko Rupp在“ 一些要记住的博客”上的验证。

翻译自: https://www.javacodegeeks.com/2013/08/custom-deserializer-in-jackson-and-validation.html

自定义jackson序列化

自定义jackson序列化_Jackson中的自定义反序列化程序和验证相关推荐

  1. jackson 序列化_jackson序列化与反序列化的应用实践

    作者 | zhouweixin 来源 | urlify.cn/iEbiAz 66套java从入门到精通实战课程分享 1 相关概念 序列化: 把对象转换为字节序列的过程称为对象的序列化 反序列化: 把字 ...

  2. java 自定义监听_Spring 中的自定义事件

    Spring 中的自定义事件 编写和发布自己的自定义事件有许多步骤.按照在这一章给出的说明来编写,发布和处理自定义 Spring 事件. 步骤 描述 1 创建一个名称为SpringExample的项目 ...

  3. activiti自定义_在Activiti中执行自定义查询

    activiti自定义 (这可能最终会出现在Activiti 5.15版本的用户指南中,但是我已经想要共享它了) Activiti API允许使用高级API与数据库进行交互. 例如,对于检索数据,查询 ...

  4. android studio 自定义字体,Android Studio中的自定义字体

    如何在android studio中创建自定义字体? 我试图使用自定义字体,我读过,我想将字体放在资产/字体. 我已经搜索了很长时间,但很难找到帮助. 我哪里错了?我真的不知道该怎么做. 我写下了所有 ...

  5. python构造自定义数据包_pytorch中的自定义数据处理详解

    pytorch在数据中采用Dataset的数据保存方式,需要继承data.Dataset类,如果需要自己处理数据的话,需要实现两个基本方法. :.getitem:返回一条数据或者一个样本,obj[in ...

  6. php 模板 自定义函数调用,thinkphp模板中使用自定义函数

    注意:自定义函数要放在项目应用目录/common/common.php中. 这里是关键. 模板变量的函数调用格式:{$varname|function1|function2=arg1,arg2,### ...

  7. android自定义进度条_Android中的自定义进度栏

    android自定义进度条 Custom progress bar in android application gives it a personal touch. In this tutorial ...

  8. 帆软自定义登录html,FineReport中如何自定义登录界面

    在登录平台时,不希望使用FR默认的内置登录界面,想通过自定义登录界面实现登录操作,内置登录界面如下图: 登录界面,获取到用户名和密码的值,发送到报表系统,报表服务带着这两个参数访问认证地址进行认证. ...

  9. java 获取自定义参数类型_Springboot中使用自定义参数注解获取 token 中用户数据...

    使用自定义参数注解获取 token 中User数据 使用背景 在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤 拦截器中截获token TokenUtil工具类 ...

最新文章

  1. 工作中搜索页面搜索记录功能的封装(存储到本地)
  2. 十大流氓骚扰软件卸载秘籍
  3. 使用AFNetworking请求新浪微博数据接口出错解决办法
  4. 【数据结构】哈夫曼树与哈夫曼编码
  5. python3.5和3.7可以共存吗_centos7下Python和python3共存
  6. python基础列表(四)
  7. swift-01-利用元组判断字符串出现次数
  8. 邪恶的编码魔咒,你中招没?
  9. Google PR 到4了
  10. js 中堆和栈的应用与理解
  11. Prototype的JSON支持
  12. go语言--正则表达式过滤数据--通过文件获取数据
  13. 将系统常用程序一次性的都安装到位
  14. 二叉树的前中后序遍历(非递归实现)
  15. 央视财经采访:康晓阳投资分享
  16. Java 8 - 并行流计算入门
  17. 微纳加工技术_工艺模块_STI 浅槽隔离
  18. 为梦想--不抛弃,不放弃!!!
  19. 如何利用COOC生成动态排名变化利器可识别的数据格式
  20. 红山vTop虚拟化桌面实施分享(一)

热门文章

  1. 汇编语言(二十七)之身份证最后一位求和校验
  2. 句法分析(syntactic parsing)在NLP领域的应用是怎样的
  3. Java集合之EnumSet
  4. C++描述杭电OJ 2005.第几天? ||
  5. mybatis和spring整合时这个报错,应该这样解决!
  6. css实现一级下拉菜单
  7. ArrayList基操
  8. 求素数为什么到平方根就行了
  9. 2016蓝桥杯省赛---java---A---10(压缩转换)
  10. 复制vmware overLay网络无法ping通 ping www.baidu.com可以