Mixin对于前端开发者可不陌生,Vue、React等知名前端框架都使用了Mixin。而对于后端开发,尤其是Java后端开发来说Mixin却是一个很陌生的概念。今天来我们通过Jackson让后端开发者也来认识一下Mixin

场景

比如我们引用了一个Jar包,其中的某个类在某个场景需要反序列化,但是这个类没有提供默认构造。咋办呢?把原来的项目拉下来,重写一下?下下策! 你可以使用Jackson提供的Mixin特性来解决这个问题。

Jackson中的Mixin

Jackson中的 Mixin(混入) 我们可以这样解读它:将目标对象无法实现的序列化或反序列化功能通过一个混入对象进行配置,在序列化或反序列化的时候把这些个性化配置混入到目标对象中。混入不改变目标对象本身的任何特性,混入对象和目标对象是映射的关系。接下来我们来实现一个混入的DEMO。

Mixin的实现

我们有一个User类,为了演示需要,我们极端一些,实际开发中不太会出现这种极端情况。这个User没有无参构造,也没有属性的getter方法。

public class User {private final String name;private final Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}

编写Mixin类

我想对这个极端的User进行序列化和反序列化。按以前的玩法我们在User类上加上@JsonAutoDetect注解就可以实现序列化了;加上@JsonDeserialize注解并指定反序列化类就可以反序列化了。不过今天我们不需要对User进行任何更改,只需要编写一个Mixin类把上述两个注解配置好就可以了。

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(using = UserMixin.UserDeserializer.class)
public abstract class UserMixin {/*** 反序列化类**/static class UserDeserializer extends JsonDeserializer<User> {@Overridepublic User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {ObjectMapper mapper = (ObjectMapper) p.getCodec();JsonNode jsonNode = mapper.readTree(p);String name = readJsonNode(jsonNode, "name").asText(null);String age = readJsonNode(jsonNode, "age").asText(null);Integer ageVal = Objects.isNull(age)? null: Integer.valueOf(age);return new User(name,ageVal);}private JsonNode readJsonNode(JsonNode jsonNode, String field) {return jsonNode.has(field) ? jsonNode.get(field) : MissingNode.getInstance();}}}

其它注解可以参考往期的Jackson文章的介绍

Mixin映射目标类

编写完Mixin类后,我们通过ObjectMapper中的addMixIn方法把UserMixinUser映射起来。并编写一个序列化和反序列化的例子。

ObjectMapper objectMapper = new ObjectMapper();objectMapper.addMixIn(User.class, UserMixin.class);User felord = new User("felord", 12);String json = objectMapper.writeValueAsString(felord);//{"name":"felord","age":12} System.out.println("json = " + json);String jsonStr = "{\"name\":\"felord\",\"age\":12}";User user = objectMapper.readValue(jsonStr, User.class);// User{name='felord', age=12}System.out.println("user = " + user);

这样我们在不对目标类进行任何改变的情况下实现了个性化的JSON序列化和反序列化。

Jackson中的Module

Jackson还提供了模块化功能,可以将个性化配置进行模块化统一管理,而且可以按需引用,甚至可插拔。它同样能够管理一组Mixin。声明一个Jackson Module非常简单,继承SimpleModule覆写它的一些方法即可。针对Mixin我们可以这样写:

public class UserModule extends SimpleModule {public UserModule() {super(UserModule.class.getName());}@Overridepublic void setupModule(SetupContext context) {context.setMixInAnnotations(User.class,UserMixin.class);}
}

Module同样可以注册到ObjectMapper中,同样也能实现我们想要的效果:

ObjectMapper objectMapper = new ObjectMapper();objectMapper.registerModule(new UserModule());// 省略

Module的功能更加强大。平常我们会使用以下几个Module:

  • jackson-module-parameter-names 此模块能够访问构造函数和方法参数的名称

  • jackson-datatype-jdk8 除了Java8的时间API外其它新特性的的支持

  • jackson-datatype-jsr310 用以支持Java8新增的JSR310时间API

另外Spring Security也提供了Module支持SecurityJackson2Modules,它包含了下面的一些模块:

ObjectMapper mapper = new ObjectMapper();mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);mapper.registerModule(new CoreJackson2Module());mapper.registerModule(new CasJackson2Module());mapper.registerModule(new WebJackson2Module());mapper.registerModule(new WebServletJackson2Module());mapper.registerModule(new WebServerJackson2Module());mapper.registerModule(new OAuth2ClientJackson2Module());

建议看一下SecurityJackson2Modules源码,研究并模仿一下Module的使用。

OAuth2.0中的scope和RBAC中的role有什么关系

2021-11-16

Spring OAuth2 授权服务器配置详解

2021-11-15

授权服务器框架Spring Authorization Server的过滤器链

2021-11-11

Spring新的授权服务器Spring Authorization Server入门

2021-11-09

推荐关注本文作者:码农小胖哥

分享高质量编程知识,探讨IT人生

技术干货,实战技巧,面试技巧,前沿资讯一个都不能少

JSON序列化和反序列化还有这种玩法相关推荐

  1. 一文读懂Json序列化与反序列化

    一文读懂Json序列化与反序列化 一文读懂Json序列化与反序列化 #mermaid-svg-tVjnnlFu6ZBDpGOQ {font-family:"trebuchet ms" ...

  2. DotNet的JSON序列化与反序列化

    JSON(JavaScript Object Notation)JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式.在现在的通信中,较多的采用JSON数据格式,JSON有 ...

  3. php json字符串序列化,JSON序列化与反序列化实现方法(附代码)

    这次给大家带来JSON序列化与反序列化实现方法(附代码),JSON序列化与反序列化实现的注意事项有哪些,下面就是实战案例,一起来看一下. 一.JSON简介 JSON(JavaScript Object ...

  4. .Net Core Json序列化和反序列化以及自定义JsonConverterT来转化特殊日期时间格式

    System.Text.Json 命名空间提供用于序列化和反序列化 JavaScript 对象表示法 (JSON) 的功能. System.Text.Json 命名空间包含所有入口点和主要类型. Sy ...

  5. C#中JSON序列化和反序列化

    有一段时间没有到博客园写技术博客了,不过每天逛逛博客园中大牛的博客还是有的,学无止境-- 最近在写些调用他人接口的程序,用到了大量的JSON.XML序列化和反序列化,今天就来总结下json的序列化和反 ...

  6. json 反序列化 父子类型_Jaskson精讲第7篇-类继承关系下的JSON序列化与反序列化JsonTypeInfo...

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的, ...

  7. Go进阶(7): JSON 序列化和反序列化

    1. json序列化和反序列化基础 json数据的序列化和反序列化是一种非常常见的方式,尤其是在http/rcp的微服务调试中. 基础语法 在 Go 中我们主要使用官方的 encoding/json  ...

  8. 序列化对象C++对象的JSON序列化与反序列化探索

    新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正 一:背景 作为一名C++开发人员,我始终很期待能够像C#与JAVA那样,可以省力的进行对象的序列化与反序列化,但到现在为止,还没有找 ...

  9. php和js序列化,PHP中serialize和json序列化与反序列化的区别

    在PHP中,serialize和json两种方式对一个对象或数组进行序列化或反序列化有什么区别呢? 假设一个对象和一个数组: PHP 1 2 3 4$web=newstdClass; $web-> ...

最新文章

  1. Canvas基础知识
  2. python爬虫能赚钱吗-在校大学生用python当爬虫一个月能赚3000吗?
  3. Java虚拟机类装载的原理及实现
  4. java中map可以为空吗_检查NavigableMap是否在Java中为空
  5. iframe实现页面无刷新上传文件(PHP)----备忘
  6. AWK高级编程 转载
  7. (46)FPGA面试题FPGA内部结构及资源
  8. websocket协议中获取 http 请求字符串
  9. Home_W的位运算(位运算+预处理)
  10. EJBCA 在windows上的安装
  11. 2008秋季-计算机软件基础-0917课堂用例(1)
  12. Vue入门之常用指令
  13. 声网Agora 孙雨润:下一代实时传输体系结构的升级与应用
  14. 使用SCI-HUB下载论文
  15. SQL Server 2017 安装AdventureWorks示例数据库出现的问题
  16. 关于 联想昭阳 E43A 无线开关设置的 正确解决办法
  17. 解决Tomcat显示中文乱码问题
  18. 企业微信标签在哪?如何设置?
  19. 搭建基于Python的数字图像识别系统(一)
  20. 情人节快乐(转)十五首最美爱情古诗词,伴你过一个温馨浪漫的情人节

热门文章

  1. SQL查询前10条记录(SqlServer/mysql/oracle)[语法分析]
  2. 使用 P3P 规范让 IE 跨域接受第三方 cookie
  3. python 并行计算 multiprocessing、multiprocess模块 简介
  4. linux 远程执行shell 获取返回值
  5. centos7离线安装metasploit
  6. SUID和SGID位简介
  7. python3 错误string indices must be integers 的解决方法
  8. alpine linux 简介(面向安全应用的发行版)apk
  9. wifi密码破解与攻击
  10. error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup