【jackson】自定义字段注解完成序列化逻辑

2023-10-26

背景

Spring默认的JSON序列化工具使用的是jacksonGitHub项目地址: https://github.com/FasterXML/jackson

我们在处理前后端接口交互的时候,可能需要实现各种各样的个性化需求,这篇文章主要介绍自定义注解,然后对特定字段进行业务逻辑处理。

本文开发环境介绍

开发依赖 版本
Spring Boot 3.1.2
JDK 17

新建一个注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JsonSerialize(using = PrintFieldJsonSerializer.class)
public @interface PrintField {

    Type rule() default Type.TYPE_1;

    enum Type {
        TYPE_1, TYPE_2
    }
}

新建一个JavaBean

在字段上使用自定义注解

import lombok.Builder;
import lombok.Data;

/**
 * @author tangheng
 */
@Data
@Builder
public class DemoPerson {

    @PrintField(rule = PrintField.Type.TYPE_1)
    private String name;
    @PrintField(rule = PrintField.Type.TYPE_2)
    private String email;
}

新建一个JsonSerializer

用来做自定义的业务逻辑

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;

@Slf4j
@RequiredArgsConstructor
public class PrintFieldJsonSerializer extends JsonSerializer<String> {

    private final PrintField.Type rule;

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if(StringUtils.isBlank(value)) {
            return;
        }
        switch (rule) {
            case TYPE_1:
                log.info("hello, value: {}", value);
                break;
            default:
                log.info("rule: {}, value: {}", rule, value);
                break;
        }
        gen.writeString(value);
    }
}

新建一个AnnotationIntrospector

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.Annotated;

import java.lang.annotation.Annotation;

public class PrintFieldAnnotationIntrospector extends AnnotationIntrospector {

    @Override
    public Version version() {
        return Version.unknownVersion();
    }

    @Override
    public Object findSerializer(Annotated a) {
        PrintField ann = _findAnnotation(a, PrintField.class);
        if (ann != null) {
            return new PrintFieldJsonSerializer(ann.rule());
        }
        return null;
    }

    @Override
    public boolean isAnnotationBundle(Annotation ann) {
        if (PrintField.class.isAssignableFrom(ann.getClass())) {
            return true;
        }
        return false;
    }
}
  • 这一步很关键,利用jackson的Introspector机制,起到承上启下的作用
  • 判断字段上有自定义注解,然后使用自定义的JsonSerializer
  • 这样就把整个事情串起来了

单元测试

class PrintFieldJsonSerializerTest extends JsonSpringbootTestBase {

    private ObjectMapper objectMapper = new ObjectMapper();

    @SneakyThrows
    @Test
    void serialize() {
        objectMapper.setAnnotationIntrospector(new PrintFieldAnnotationIntrospector());

        DemoPerson demoPerson = DemoPerson.builder()
                .name("zhangsan")
                .email("zhangsan@163.com")
                .build();

        String testResult = objectMapper.writeValueAsString(demoPerson);
        log.info("testResult: {}", testResult);
        assertTrue(StringUtils.isNotBlank(testResult));
    }
}

单元测试结果截图
在这里插入图片描述

总结

  • 实现一个需求的道路有千万条,对于一个有追求的程序员,研究源码,找到一条最精炼的路,用最简洁的方式实现目标,在可扩展性、可维护性方面都较优
  • 有需求的时候,不要着急写代码,研究下源码,可以帮助我们优雅的达到目的
  • 也许研究源码的时间远远大于写代码的时候,但收获和成就感还是很满足的
  • 即使最终仅用用几行代码实现需求,但一个优秀的程序员从来不是以代码的行数来衡量的
  • jackson的反序列化可以参考同样的原理来实现
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【jackson】自定义字段注解完成序列化逻辑 的相关文章

  • 使用 Spring Session 时自定义 cookie 名称

    我正在使用 Spring Sessions v1 0 1 我已经使用 XML 配置设置了应用程序 我现在需要根据某些属性更改默认的 SESSION cookie 名称 例如myApp SESSION其中 myApp 将从属性文件中读取 我注
  • 使用 libGDX 写入 Json

    我是 Json 和 libGDX 的新手 但我创建了一个简单的游戏 我想将玩家姓名及其分数存储在 Json 文件中 有没有办法做到这一点 我想创建一个 Json 文件Gdx files localStorage如果它不存在 如果存在 则向其
  • 无法在 Struts 中加载配置

    我正在尝试在在线考试中实现 STRUTS Spring 和 HIBERNATE 集成 使用 apache tomcat 7 0 42 在 Eclipse Kepler 中运行项目时 它会抛出以下错误 HTTP Status 404 Onli
  • pyodbc 返回的行不可 JSON 序列化

    我正在尝试使用 Python 中的 pyodbc 库检索表的行 我能够成功检索表和表的字段 现在我有一个名为 apx roomtypes 的表 其数据如下 但是 当我将 pyodbc 行附加到列表 然后尝试将列表转储到 JSON 时 出现错
  • 当列表只有一个元素时,CXF 返回对象而不是 js 数组

    我正在使用 CXF 来创建宁静的服务 其中一项服务返回一个字符串列表 当列表中有多个项目时 CXF 返回一个字符串数组 但当我只有一个元素时 它返回字符串而不是带有 json 的数组 对于一件物品 ImageResponse images
  • LDAP中超时的实现

    我一直在处理我们正在使用的应用程序LDAP获取用户详细信息 有时获取用户详细信息需要更多时间 我想实施time out获取详细信息的方法 以便我们可以避免在最坏的情况下在服务器中挂起事务 这里我们使用的是LdapUtil我们在其中配置的类L
  • AJV自定义关键字验证

    我正在使用 AJV 库来验证我的 JSON 架构 我希望能够验证Startdate成为一个字符串 如果不是字符串 则应将其转换为N A 目前 它仅转换undefined to N A 但是 在这些情况下 它不会按预期工作 null gt 空
  • 将 JSON 与嵌套数组和 json 进行比较(数组顺序无关紧要)

    你好 我正在尝试比较java中的两个json 每个键可以包含一个json对象或json对象数组 并且它们中的每个也可以是数组或json 这是 Json 的示例 id 123123asd123 attributes name apps val
  • Apache NiFi ExecuteScript:通过映射文件替换 Json 值的 Groovy 脚本

    我正在 Groovy 脚本上使用 Apache NiFi 0 5 1 以将传入的 Json 值替换为映射文件中包含的值 映射文件如下所示 它是一个简单的 txt Header1 Header2 Header3 A some text A2
  • 导致:org.eclipse.jgit.api.errors.RefNotFoundException:Ref master 无法解析

    我正在尝试Spring Boot 2 4 2 RELEASE并正在发展config server对于我的微服务项目 以下是我迄今为止开发的代码 配置服务器应用程序 java SpringBootApplication EnableConfi
  • Elasticsearch TransportClient NetworkPlugin NoClassDefFoundError

    我期待将 Elasticsearch 集成到 Spring Boot Web 应用程序中 这是创建传输客户端的配置 Configuration public class ElasticsearchConfig private Transpo
  • AngularJS:使用控制器和 ng-repeat 重新加载 div 上的数据

    我是 Angular JS 的新手 正在学习它 我有一个 div 并在启动时使用控制器从 json 加载数据 代码如下 但我想在执行特定操作后 json 对象发生更改时再次重新加载它 索引 html DOCTYPE html PUBLIC
  • 将数组转换为 Json [重复]

    这个问题在这里已经有答案了 可能的重复 在 jQuery 中序列化为 JSON https stackoverflow com questions 191881 serializing to json in jquery 将对象转换为 JS
  • 组合类中的多态 lift-json 反序列化

    我正在尝试使用 Lift Json 自动将 json 对象反序列化为 scala 类 其中的坐标类用于存储 GeoJson 信息 case class Request name String geometry Geometry sealed
  • 如何使用各个属性中的所有验证属性序列化模型?

    上下文 使用 mvc 控制器方法创建 jsonP 服务 该服务提供表单字段的定义 包括所有验证规则 我的问题是我不知道如何序列化验证属性 我更喜欢验证属性的格式与在常规 Mvc 视图中使用不显眼的验证时由 Razor 序列化的格式相同 为了
  • 如何发送/接收 JSON?

    我知道这是一个愚蠢的问题 但我通常不进行 Web 编程 并且被要求发送一些 JSON 数据并接收一些回报 我用谷歌搜索 很清楚如何编码和解码 JSON 数据 但我对此很陌生 我不知道如何与给定的 URL 进行通信并说 这里有一些数据 请发回
  • Spring Security“拒绝执行来自...的脚本”

    我正在 HTML 文件 thymeleaf 模板 中使用 Spring Security 和 Bootstrap 构建 Spring MVC 应用程序 Spring Security部分基于Spring Guide对于春季安全 http s
  • JSON.stringify / 解析带有引号的奇怪内容

    我在解析一些包含引号的 JSON 时遇到了一个奇怪的小问题 我正在使用本机 JSON stringify 和 JSON parse 函数来执行此操作 如果我将一个对象 其中有引号的对象 字符串化 它们就会像人们所期望的那样被转义 如果我然后
  • Spring:当我的类已经用@RestController注释时,为什么我仍然应该使用@RequestBody?

    我目前正在将 Java 和 Spring 用于我的 Web 服务应用程序 我正在使用 RestController希望消除使用注释的需要 ResponseBody and RequestBody注释 不幸的是 删除 RequestBody注
  • 更新(合并)时缺少 Spring Data JPA 验证

    我正在使用 Spring Boot 1 5 4 RELEASE 和 Spring Data JPA 进行项目 遇到更新实体时未执行 Hibernate 验证器或至少在某些情况下未验证的问题 For Person如下所示 禁止使用空名称 并且

随机推荐

  • SpringBoot+easypoi+vue导出word文档

    因为项目需求需要 临时写的有什么错误的地方望各位见谅 可以借鉴参考 easypoi依赖包
  • 在 Kylin 中实现异常值检测 UD(A)F

    本文讲解了时间序列数据异常值检测的基本概念和在 Kylin 中开发使用异常值检测 UDF 的方法 可以作为其他 UDF 开发的参考 通过在 Kylin 中移植 Hivemall 的 UDF 我们可以充分利用 Kylin 的优势 减少直接使用
  • TrafficMonitor安装报错

    由于找不到VCRUNTIME140 dll 无法继续执行代码 重新安装程序可能会解决次问题 解决方法 安装完 Visual Studio 2019后 就可以安装上了
  • STM32——一文完全读懂IIC通信

    文章目录 I2C基本概念 硬件线路 通信结构 I2C设备地址 I2C数据传输 I2C时钟速度和通信速度 I2C应答机制 I2C设备之间的冲突检测 I2C设备规格 主机读取数据 IIC通信过程 实际编程和应用 IO 口模拟 IIC 总线 常见
  • 服务器常用命令

    服务器常用命令 1 查看安装的软件 ps ef grep nginx 2 端口被占用 netstat anp grep 8801 2 2 通过程序名查询进程号 ps aux grep 程序名 2 3 通过进程号查询进程详细信息 ps ef
  • 【js】Object的常用方法

    Object assign target source 查看 Object entries 返回一个键值对数组查看 Object prototype toString call 查看
  • Redis的内存淘汰机制和删除策略

    Redis内存淘汰机制 Redis内存淘汰指的是用户存储的一些键被可以被Redis主动地从实例中删除 内存的淘汰机制的初衷是为了更好地使用内存 配置 我们可以通过配置redis conf中的maxmemory这个值来开启内存淘汰功能 这个值
  • 【Python函数】——sort,sorted

    1 sorted和sort的常规使用 2 关于自定义比较函数 3 试验 from functools import cmp to key ll 2 3 10 1 2 3 5 6 7 2 5 10 2 4 10 根据一个维度进行排序 这里根据
  • sqli-labs Less-25、25a(sqli-labs闯关指南 25、25a)

    目录 Less 25 Less 25a Less 25 GET 基于错误 您所有的OR AND都属于我们 字符串单引号 源码 本关主要将 or and 进行了大小写的过滤 将其换成空 如何绕过 or 和 and 过滤 一般性提供以下几种思路
  • 国内第一篇讲解减少卡顿的代码级详细文章

    原文链接 原文链接 系统网站应用出现过卡顿 但却不知道如何优化 国内第一篇讲如何减少卡顿的代码级别详细文章 也是性能优化系列文章中的一篇 欢迎点赞 关注 也欢迎对其中的内容进行评论 经常听人说 不要阻塞主线程 或者 减少长耗时 该如何做呢
  • SQL Server 数据分页查询

    最近学习了一下SQL的分页查询 总结了以下几种方法 首先建立了一个表 随意插入的一些测试数据 表结构和数据如下图 现在假设我们要做的是每页5条数据 而现在我们要取第三页的数据 数据太少 就每页5条了 方法一 select top 5 fro
  • 火星数字

    火星人是以 13 进制计数的 地球人的 0 被火星人称为 tret 地球人数字 1 到 12 的火星文分别为 jan feb mar apr may jun jly aug sep oct nov dec 火星人将进位以后的 12 个高位数
  • attr 'explicit_paddings',tensorflow迁移到安卓报错不能载入模型

    attr explicit paddings tensorflow迁移到安卓报错不能载入模型 Android Stdio中报错 Caused by java io IOException Not a valid TensorFlow Gra
  • 第十章 网络工具--基于Linux3.10

    在测试io设备时 常常会用到iostat iotop工具 在查看内存时常常用到vmstat free slabtop工具 在查看调度器时 常常使用mpstat top以及ps工具 这里来说说网络相关的工具 有性能分析 网络管理 状态查看类工
  • App逆向案例 X嘟牛 - Frida监听 & WT-JS工具还原(一)

    App逆向案例 X嘟牛 Frida监听 WT JS工具还原 一 提示 文章仅供参考 禁止用于非法途径 文章目录 App逆向案例 X嘟牛 Frida监听 WT JS工具还原 一 前言 一 资源推荐 二 App抓包分析 三 反编译逆向分析 四
  • 2023华为产品测评官-开发者之声

    2023华为产品测评官 开发者之声 活动激发了众多开发者和技术爱好者的热情 他们纷纷递交了精心编写的产品测评报告 活动社群充满活力 参与者们热衷于交流讨论 互相帮助解决问题 一起探索云技术的无限可能 在此次活动中 华为云CodeArts获得
  • 守护线程

    守护线程是一类比较特殊的线程 一般用于处理后台的工作 比如JDK的垃圾回收线程 守护线程具备自动结束生命周期的特点 非守护线程不具备这样的特点 首先明确一个问题 JVM什么情况下会退出 The java virtual machine ex
  • 关于H.248的树图规则

    一 H248数图 数图可以是一个字符串 我们不妨称之为数图字符串 它遵循了Unix系统命令中的规则表达式的语法规定 也可以是许多数图字符串的并集 之间用 分隔 我们不妨称之为数图字符串列表 以下是一个数图的例子 2 8 xxxxxxx 13
  • RabbitMQ 与 Kafka 对比

    作为一个有丰富经验的微服务系统架构师 经常有人问我 应该选择RabbitMQ还是Kafka 基于某些原因 许多开发者会把这两种技术当做等价的来看待 的确 在一些案例场景下选择RabbitMQ还是Kafka没什么差别 但是这两种技术在底层实现
  • 【jackson】自定义字段注解完成序列化逻辑

    目录 背景 本文开发环境介绍 新建一个注解 新建一个JavaBean 新建一个JsonSerializer 新建一个AnnotationIntrospector 单元测试 总结 背景 Spring默认的JSON序列化工具使用的是jackso