java:jackson 一:Jackson Annotation

news2024/9/27 5:41:50

java:jackson 一:Jackson Annotation

1 前言

参考文档地址:

https://www.baeldung.com/jackson

https://www.baeldung.com/jackson-annotations

2 使用

2.1 Jackson Serialization Annotations

jackson 序列化注解


2.1.1 @JsonAnyGetter

The @JsonAnyGetter annotation allows for the flexibility of using a Map field as standard properties.

package com.xiaoxu.test.jackson;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.text.StringEscapeUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author xiaoxu
 * @date 2022-12-21
 * spring_boot:com.xiaoxu.test.jackson.TestJaskSon
 */
public class TestJaskSon {

    public static void main(String[] args) throws Exception{
        ExtendableBean bean = new ExtendableBean("My bean");
        bean.add("attr1", "val1");
        bean.add("attr2", "val2");

        System.out.println(bean);

        String result = new ObjectMapper().writeValueAsString(bean);
        System.out.println(result);

        String a = "{\\\"name\\\":\\\"xiaoxu\\\",\\\"age\\\":\\\"27\\\"}";
        String s = StringEscapeUtils.unescapeJava(a);
        System.out.println(s);
        UseRR useRR = JSON.parseObject(s, UseRR.class);
        System.out.println(useRR);
    }
}

class UseRR{
    String name;

    String age;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UseRR{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

class ExtendableBean {
    public String name;
    private Map<String, String> properties;

    ExtendableBean(String name){
        this.name = name;
        this.properties = new HashMap<>();
    }

    public void add(String key,String value){
        this.properties.put(key,value);
    }

    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }

    @Override
    public String toString() {
        return "ExtendableBean{" +
                "name='" + name + '\'' +
                ", properties=" + properties +
                '}';
    }
}
ExtendableBean{name='My bean', properties={attr2=val2, attr1=val1}}
{"name":"My bean","attr2":"val2","attr1":"val1"}
{"name":"xiaoxu","age":"27"}
UseRR{name='xiaoxu', age='27'}

可见,@JsonAnyGetter加在Map属性的get方法上时,打印的json字符串为将Map属性的key、value也直接展示在json结果中了。


2.1.2 @JsonGetter

The @JsonGetter annotation is an alternative to the @JsonProperty annotation, which marks a method as a getter method.

先观察@JsonProperty的使用:

如下DTO的name属性的set和get方法名称,不是传统的setter、getter方法名称:

package test.jackson;

import lombok.AllArgsConstructor;

/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonDTO
 */
@AllArgsConstructor
public class JacksonDTO {
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getMyName() {
        return name;
    }

    public void setMyName(String name) {
        this.name = name;
    }
}
package test.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonAnnotationTest
 */
public class JacksonAnnotationTest {
    private static final ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
    }

    public static void demo1() throws Exception{
        JacksonDTO jacksonDTO = new JacksonDTO(1,"xiaoxu");
        System.out.println(objectMapper.writeValueAsString(jacksonDTO));
    }

    public static void main(String[] args) throws Exception{
        demo1();
    }

}

上述执行结果如下,可见序列化后,不为name,是myName:

{
  "id" : 1,
  "myName" : "xiaoxu"
}

使用@JsonProperty:

package test.jackson;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;


/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonDTO
 */
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class JacksonDTO {
    @JsonProperty(value = "mid")
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @JsonProperty(value = "xName")
    public String getMyName() {
        return name;
    }

//    @JsonProperty(value = "xName")
    public void setMyName(String name) {
        this.name = name;
    }
}
package test.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * @author xiaoxu
 * @date 2022-12-27
 * java_demo:test.jackson.JacksonAnnotationTest
 */
public class JacksonAnnotationTest {
    private static final ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
    }

    public static void demo1() throws Exception{
        JacksonDTO jacksonDTO = new JacksonDTO(1,"xiaoxu");
        System.out.println(objectMapper.writeValueAsString(jacksonDTO));
        /* 反序列化的前提:需要有无参构造方法,否则报错:
        *
        * (no Creators, like default constructor, exist):
        * cannot deserialize from Object value (no delegate- or property-based Creator)
        *  */
        JacksonDTO jacksonDTO1 = objectMapper.readerFor(JacksonDTO.class)
                .readValue(objectMapper.writeValueAsString(jacksonDTO));
        System.out.println(jacksonDTO1);
    }

    public static void main(String[] args) throws Exception{
        demo1();
    }

}

序列化结果:

{
  "mid" : 1,
  "xName" : "xiaoxu"
}
JacksonDTO(id=1, name=xiaoxu)

@JsonGetter可替代如上@JsonProperty注解使用:

在这里插入图片描述

再次执行,序列化的效果一致:

在这里插入图片描述


2.1.3 @JsonPropertyOrder

We can use the @JsonPropertyOrder annotation to specify the order of properties on serialization.

@JsonPropertyOrder主要是更新序列化后的结果的字段顺序,如果同时存在使用了@JsonProperty注解,必须按照@JsonProperty注解的value设置值,才能更新顺序成功(无法匹配则没有效果)。

@ToString
@AllArgsConstructor
@NoArgsConstructor
@JsonPropertyOrder(value = {"xxName","mid"})
public class JacksonDTO {
    @JsonProperty(value = "mid")
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @JsonGetter(value = "xxName")
    public String getMyName() {
        return name;
    }

//    @JsonProperty(value = "xName")
    public void setMyName(String name) {
        this.name = name;
    }
}

再次执行,DTO的字段顺序改变:

在这里插入图片描述


2.1.4 @JsonRawValue

The @JsonRawValue annotation can instruct Jackson to serialize a property exactly as is.

@ToString
@AllArgsConstructor
@NoArgsConstructor
/* 序列化时,有getter方法即可 */
@Getter
public class JacksonDTO1 {
    int id;
    String name;
    @JsonRawValue
    String jsonData;
}
JacksonDTO1 jacksonDTO1 = new JacksonDTO1(1,"xiaoxu","{\"myName\":\"xiaoxu\",\"age\":\"55\"}");
System.out.println(objectMapper.writeValueAsString(jacksonDTO1));

执行结果:

{
  "id" : 1,
  "name" : "xiaoxu",
  "jsonData" : {"myName":"xiaoxu","age":"55"}
}

2.1.5 @JsonValue

@JsonValue indicates a single method that the library will use to serialize the entire instance.

For example, in an enum, we annotate the getName with @JsonValue so that any such entity is serialized via its name.

enum JackEnum{
    Study("study",1234);

    private String code;
    private long value;

    JackEnum(String code, long value){
        this.code = code;
        this.value = value;
    }

    @JsonValue
    public String getCode() {
        return code;
    }

    public long getValue() {
        return value;
    }
}
System.out.println(objectMapper.writeValueAsString(JackEnum.Study));

执行结果:

"study"

2.1.6 @JsonRootName

The @JsonRootName annotation is used, if wrapping is enabled, to specify the name of the root wrapper to be used.

Wrapping means that instead of serializing a User to something like:

@ToString
@AllArgsConstructor
@NoArgsConstructor
/* 序列化时,有getter方法即可 */
@Getter
@JsonRootName(value = "specialPerson")
class JacksonDTO2 {
    int id;
    String name;
}
/* 不增加 objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
* @JsonRootName(value = "specialPerson") 将不会生效
*  */
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
JacksonDTO2 jacksonDTO2 = new JacksonDTO2(1,"xiaoxu");
System.out.println(objectMapper.writeValueAsString(jacksonDTO2));

执行结果:

{
  "specialPerson" : {
    "id" : 1,
    "name" : "xiaoxu"
  }
}

2.1.7 @JsonSerialize

We’re going to use @JsonSerialize to serialize the eventDate property with a CustomDateSerializer:

该注解常用于和自定义序列化(或类似@JsonDeserialize,与自定义反序列化)器一同使用

使用参考如下:

https://blog.csdn.net/a232884c/article/details/128418713

2.2 Jackson Deserialization Annotations

jackson 反序列化注解


2.2.1 @JsonCreator

We can use the @JsonCreator annotation to tune the constructor/factory used in deserialization.

It’s very useful when we need to deserialize some JSON that doesn’t exactly match the target entity we need to get.

去掉@JsonCreator,只使用@JsonProperty,效果是一样的:

@ToString
class JacksonDTO3 {
    int id;
    String name;

    /* 构造方法为反序列化时的myName,映射为name */
    @JsonCreator
    public JacksonDTO3(@JsonProperty("id") int id,
                       @JsonProperty("myName") String name){
        this.id = id;
        this.name = name;
    }
}
String value = "{\"id\":\"123\",\"myName\":\"xiaoxu\"}";
JacksonDTO3 dto3 = objectMapper.readerFor(JacksonDTO3.class)
        .readValue(value);
System.out.println(dto3);

执行结果:

JacksonDTO3(id=123, name=xiaoxu)

2.2.2 @JacksonInject

@JacksonInject indicates that a property will get its value from the injection and not from the JSON data.

In the following example, we use @JacksonInject to inject the property id:

@ToString
class JacksonDTO4 {
    @JacksonInject
    int id;
    String name;

    /* id 是注入的, 但是name反序列化时,取的jsonData中的,
    * 必须加上getter方法,否则将会抛出异常
    *  */
    public String getName() {
        return name;
    }
}
String value = "{\"name\":\"xiaoxu\"}";
InjectableValues inject = new InjectableValues.Std().addValue(int.class, 666);
JacksonDTO4 dto4 = objectMapper.reader(inject)
        .forType(JacksonDTO4.class)
        .readValue(value);
System.out.println(dto4);

执行结果:

JacksonDTO4(id=666, name=xiaoxu)

2.2.3 @JsonAnySetter

@JsonAnySetter allows us the flexibility of using a Map as standard properties. On deserialization, the properties from JSON will simply be added to the map.

@ToString
class ExtendableBean {
    public String name;
    private final Map<String, String> properties = new HashMap<>();

    @JsonAnySetter
    public void add(String key, String value) {
        properties.put(key, value);
    }
}
String json
        = "{\"name\":\"xiaoxu\",\"attr2\":\"val2\",\"attr1\":\"val1\"}";

ExtendableBean bean = objectMapper
        .readerFor(ExtendableBean.class)
        .readValue(json);
System.out.println(bean);

执行结果:

ExtendableBean(name=xiaoxu, properties={attr2=val2, attr1=val1})

2.2.4 @JsonSetter

@JsonSetter is an alternative to @JsonProperty that marks the method as a setter method.

This is incredibly useful when we need to read some JSON data, but the target entity class doesn’t exactly match that data, and so we need to tune the process to make it fit.

此注解和@JsonGetter效果类似,只是用于的是反序列化

@ToString
class JacksonDTO5 {
    int id;
    String name;

    /* 反序列化时,id 有setter或者getter方法均可 */
    public void setId(int id) {
        this.id = id;
    }

    @JsonSetter("name")
    public void setMyName(String name) {
        this.name = name;
    }
}
String value = "{\"id\":\"123999\",\"name\":\"xiaoxu\"}";
JacksonDTO5 dto5 = objectMapper.readerFor(JacksonDTO5.class)
        .readValue(value);
System.out.println(dto5);

执行结果:

JacksonDTO5(id=123999, name=xiaoxu)

2.2.5 @JsonDeserialize

@JsonDeserialize indicates the use of a custom deserializer.

该注解@JsonDeserialize用于和自定义反序列化器一同使用

使用参考如下:

https://blog.csdn.net/a232884c/article/details/128407205

2.2.6 @JsonAlias

The @JsonAlias defines one or more alternative names for a property during deserialization.

@ToString
class JacksonDTO6 {
    int id;
    @JsonAlias(value = {"f_name","frName"})
    String fruitName;

    /* 反序列化时,id 有setter或者getter方法均可 */
    public void setId(int id) {
        this.id = id;
    }

    /* 反序列化时,fruitName 有setter或者getter方法均可 */
    public String getFruitName() {
        return fruitName;
    }
}
String value = "{\"id\":\"123888\",\"frName\":\"xiaoxu\"}";
JacksonDTO6 dto6 = objectMapper.readerFor(JacksonDTO6.class)
        .readValue(value);
System.out.println(dto6);

执行结果:

JacksonDTO6(id=123888, fruitName=xiaoxu)

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

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

相关文章

产业互联网是以大数据、云计算、AI等为代表的数字技术的出现为标志

事实上&#xff0c;以往&#xff0c;我们所经历的那个互联网玩家频出的年代&#xff0c;其实就是一个以互联网技术为主导的年代。在那样一个年代里&#xff0c;互联网技术几乎是解决一切痛点和难题的万能解药&#xff0c;几乎是破解一切行业痛点和难题的杀手锏。任何一个行业&a…

数据可视化③:大学生就业数据分析

大学生就业是和我们息息相关的话题&#xff0c;每一位大学生都关注着&#xff0c;我们常常在网络上看到有关大学生就业的话题&#xff0c;比如毕业季的一些讨论。在大一的创新创业课中&#xff0c;我们也了解到自己所学的专业和以后如何就业&#xff0c;往哪方面就业。但我们了…

深度学习目标检测_IOU、Precision、Recall、AP、mAP详解

文章目录背景IOU&#xff1a;Intersection Over Unionprecision&#xff08;精度&#xff09;和recall&#xff08;召回率&#xff09;TP、TN 、FP 、FNAP和mAP首先回顾两个概念PR曲线AP(Average Precision&#xff09;mAP(mean Average Precision)背景 目标检测的任务是找出图…

[oeasy]python0035_ 整合shell编程_循环_延迟_清屏

整合shell编程 回忆上次内容 用\r 可以让输出位置回到行首原位刷新时间 如果想要的是大字符效果 需要使用 figlet但同时还希望能刷新这可能吗&#xff1f;&#x1f914; 建立脚本 我们得熟悉一下shell 先新建一个test.sh vi test.sh python3 show_time.py python3 show_time.…

如何通过GB35114国密标准接入到LiveGBS GB28181/GB35114监控平台

1.1 安装LiveGBS GB28181/GB35114视频平台 1.2 获取设备端证书给平台 我们用LiveNVR做为设备端向LiveGBS注册&#xff0c;这里先将LiveNVR的证书导出&#xff0c;并给LiveGBS端。 本地自签名证书是LiveNVR自己给自己签发的证书。如果需要用第三方机构的证书&#xff0c;可点击…

【软件测试】资深测试的总结,有限时间找最有价值bug......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试团队的新同事&a…

Mybatis进阶之自定义TypeHandler

实际应用开发中的难免会有一些需求要自定义一个TypeHandler &#xff0c;比如这样一个需求&#xff1a;前端传来的性别是 男, 女&#xff0c;但是数据库定义的字段却是tinyint 类型&#xff08; 1:男 2:女&#xff09;。此时可以自定义一个年龄的类型处理器&#xff0c;进行转换…

Linux学习笔记——Linux实用操作(一)

04、Linux实用操作 4.1、各类小技巧&#xff08;快捷键&#xff09; 学习目标&#xff1a; 掌握各类实用小技巧 强制停止退出、登出历史命令搜索光标移动 1、Ctrlc强制停止 Linux某些程序的运行&#xff0c;如果想要强制停止它&#xff0c;可以使用快捷键Ctrlc 命令输入…

一个基于Vue+SpringBoot的个人博客项目,含数据库文件

blogSpringBoot 项目介绍 完整代码下载地址&#xff1a;一个基于VueSpringBoot的个人博客项目&#xff0c;含数据库文件 该项目是个人博客项目&#xff0c;采用Vue SpringBoot开发。 后台管理页面使用Vue编写&#xff0c;其他页面使用Thymeleaf模板。 项目演示地址&#…

什么是 MySQL 的“回表”?

1. 索引结构 要搞明白这个问题&#xff0c;需要大家首先明白 MySQL 中索引存储的数据结构。这个其实很多小伙伴可能也都听说过&#xff0c;BTree 嘛&#xff01; BTree 是什么&#xff1f;那你得先明白什么是 B-Tree&#xff0c;来看如下一张图&#xff1a; 前面是 B-Tree&am…

不止稳定快速,看华为云CDN如何在国际云服务市场中“分蛋糕”

互联网时代&#xff0c;网络的应用已十分普及&#xff0c;但依然存在下载慢、网络卡顿的现象。如企业业务运行过程中出现的卡顿现象导致数据延时&#xff1b;各校因疫情等原因网课时间长、访问应用人数过多&#xff0c;造成网络卡顿现象严重&#xff0c;无法带来良好的上课体验…

ArcGIS基础实验操作100例--实验16对字段自定义赋值

本实验专栏来自于汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 基础编辑篇--实验16 对字段自定义赋值 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1…

玩转云服务器,怎样用云服务器架设搭建游戏:浪剑天下架设教程,手把手教你架设游戏服务器,小白一看就会

服务器详情&#xff1a;服务器系统&#xff1a;LINUX-CENTOS7.6服务器配置&#xff1a;2核4G以上配置 搭建教程&#xff1a; 第一步&#xff1a;安装宝塔&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh &…

Allegro如何输出IPC文件操作指导

Allegro如何输出IPC文件操作指导 IPC文件是PCB上所有网络连接关系文件,在PCB生产前网表比对必须的文件,如下图 如何输出IPC文件,具体操作如下 选择File选择IPC356

磁实验比较-反激式变压器(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

代码随想录拓展day5 129. 求根节点到叶节点数字之和;1382.将二叉搜索树变平衡;100. 相同的树;116. 填充每个节点的下一个右侧节点指针

代码随想录拓展day5 129. 求根节点到叶节点数字之和&#xff1b;1382.将二叉搜索树变平衡&#xff1b;100. 相同的树&#xff1b;116. 填充每个节点的下一个右侧节点指针 全部都是关于二叉树的题目&#xff0c;对二叉树的遍历方式又是一个复习。 129. 求根节点到叶节点数字之…

Java 访问权限控制

使用访问权限控制的原因&#xff1a; 使用户不要触碰到那些不该触碰的部分类库设计者可以更改类的内部工作模式&#xff0c;而不必担心整体程序造成影响 访问权限修饰词 Java具有三种访问权限修饰词(public private protected)&#xff0c;划分出了四种访问权限(public prot…

WeakHashMap引起内存溢出,线程数剧增

1.问题背景 代码通过jarLoader的方式&#xff0c;实现了一个数据库多个客户端版本兼容的情况&#xff0c;一个客户端使用一个jarLoader&#xff0c;实现jar的隔离。 同时&#xff0c;jarLoader使用weekhashmap做缓存。 hive做批量查询表的元数据时&#xff0c;引入了线程池。…

NodeJS学习笔记一

文章目录1. 模块化1.1 模块作用域2. 内置API模块3. 自定义模块3.1 向外共享模块作用域中的成员3.2 使用误区3.3 CommonJS模块化规范4. 第三方API模块4.1 npm包管理目录4.2 包管理配置文件 package.json4.3 devDependencies节点4.4 切换npm的包镜像源4.5 包的分类4.5.1 项目包4.…

【cfeng-Work】work项目理解

work 项目 内容管理入职项目环境搭建商用项目 和 学习项目经验分享easily 分享work 见解 学习项目&#xff08;非商用&#xff09;相比工作中的商用项目差别还是很大的… Cfeng 最近开始工作&#xff0c; 接下来我将分享一下对于学校中的project环境和 work环境的相关理解 入职…