@JsonCreator和@JsonValue

文章目录

  • 1、正常反序列化的过程
  • 2、@JsonCreator
  • 3、@JsonValue
  • 4、应用:枚举类中校验传参以及优化前后端数据交互
  • 5、补充:@ConstructorProperties

1、正常反序列化的过程

反序列化时,默认会调用实体类的无参构造来实例化一个对象,然后使用setter来初始化属性值。写点测试代码:

@AllArgsConstructor
@Data
public class Book {

    private String name;

    private Double price;

}

测试下:

public class TestSome1 {

    @Test
    void testJson() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        Book book = objectMapper.readValue("{\n" +
                "    \"name\":\"Java\",\n" +
                "    \"price\":666.00\n" +
                "}", Book.class);
        System.out.println(book);
       
    }
}

此时,运行会抛出InvalidDefinitionException:

在这里插入图片描述

2、@JsonCreator

@JsonCreator可用在:

  • 构造方法上
  • 静态的工厂方法上

加了@JsonCreator注解,该类的对象在反序列化时,就走有@JsonCreator注解的方法来反序列化,原先无参+set的过程失效。

上面的Book类,可改成:

//@AllArgsConstructor
@Getter
public class Book {

    private String name;

    private Double price;

    @JsonCreator
    public Book(@JsonProperty("name") String name,@JsonProperty("price") Double price ){
        System.out.println("@JsonCreator生效");
        this.name = name;
        this.price = price+1;
    }
   
}

上面的@JsonProperty注解就是指定传参名和对象属性关系的,有点像MyBatis的@Param

 public Book(@JsonProperty("name") String name,@JsonProperty("price") Double price ){

@JsonCreator放在静态方法上就是:

@AllArgsConstructor
@Getter
public class Book {

    private String name;

    private Double price;

    @JsonCreator
    public static Book unSerialize(){
        System.out.println("正在反序列化成对象");
        return new Book("111",1.00);
    }

   
}

以@JsonCreator放在构造方法上为例,再运行前面的单元测试,看下反序列化的效果:

在这里插入图片描述

3、@JsonValue

@JsonValue注解可用在:

  • get方法
  • 属性字段上

一个类只能用一个,加上这个注解时,该类的对象序列化时就会只返回这个字段的值做为序列化的结果。

比如一个枚举类的get方法上加上该注解,那么在序列化这个枚举类的对象时,返回的就是枚举对象的这个属性,而不是这个枚举对象的序列化json串。继续改造上面的Book类:

@AllArgsConstructor
@Getter
public class Book {

    //@JsonValue,加get方法或者这个属性上,都一样
    private String name;

    private Double price;

    @JsonCreator
    public static Book doSerialize(){
        System.out.println("正在反序列化成对象");
        return new Book("111",1.00);
    }

    /**
     * 序列化时,序列化成我return的值,即当前对象的name属性
     */
    @JsonValue
    public String getName(){
        return this.name;
    }
}

单元测试中看下效果:

public class TestSome1 {

    @Test
    void testJson() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        Book book = objectMapper.readValue("{\n" +
                "    \"name\":\"Java\",\n" +
                "    \"price\":666.00\n" +
                "}", Book.class);
        System.out.println(book);
        System.out.println("=======");
        //序列化
        System.out.println(objectMapper.writeValueAsString(book));
    }
}

在这里插入图片描述

4、应用:枚举类中校验传参以及优化前后端数据交互

比如定义一个排序字段的枚举类,排序字段要拼到mapper层的SQL,所以其传参的合法性必须校验,每次在Service层校验,很繁琐。引入@JsonCreator:

@AllArgsConstructor
@Getter
public enum OrderFieldEnum {

    CREATE_TIME("createTime","create_time"),
    USER_NAME("userName","user_name");

    private final String value;
    private final String field;
    private static final Map<String,OrderFieldEnum> map = new HashMap<>(3);

    @JsonCreator
    public static OrderFieldEnum unSerializer(String value){
    	//把以value为key,以枚举对象为value,存进map
        if(map.isEmpty()){
            for (OrderFieldEnum fieldEnum : OrderFieldEnum.values()) {
                map.put(fieldEnum.value,fieldEnum);
            }
        }
        //map中找不到就是超出范围
        if(!map.containsKey(value)){
            throw new RuntimeException("超出范围");
        }
        return map.get(value);
    }

    @JsonValue
    public String getValue(){
        return this.value+"@JsonValue";   //这里刻意加个@JsonValue,方便后面验证序列化效果。return this.value就行。
    }


}

此时,前端传个dto(json)过来,dto里有个参数的类型是枚举类型,反序列化json成dto对象时,枚举类型的属性也会反序列化,上面@JsonCreator定义的unSerializer方法执行,就会完成参数合法性校验,Service层省事了。至于序列化:

@JsonValue
public String getValue(){
    return this.value;
}

比如需要返给前端枚举值展示下拉框,就直接Vo里就直接List<Enum> enumList,而不用定义个List<String> enumList,再反复getValue:

enumList.add(ENUM1.getValue)  
enumList.add(ENUM2.getValue)
...

因为返给前端时,Vo对象序列化,里面的一个个枚举对象也序列化,而JsonValue已经指定了序列化枚举对象时就把它的value返回就行。写个简单接口看下效果,定义个dto:

@Data
public class JsonDto {

    private String id;

    private OrderFieldEnum orderField;
}

Service层demo:

@Service
public class MyService {

    public List<OrderFieldEnum> listValue(JsonDto dto){
        System.out.println(dto.getOrderField());
        //直`List<Enum>
        List<OrderFieldEnum> list = List.of(OrderFieldEnum.CREATE_TIME, OrderFieldEnum.USER_NAME);
        return list;
    }
}

controller:

@RestController
public class CodeController {

    @Resource
    private MyService myService;

    @PostMapping("/test")
    public List<OrderFieldEnum> getStr(@RequestBody JsonDto dto){

        return myService.listValue(dto);
    }
}

异常传参时:

在这里插入图片描述

正常传参:

在这里插入图片描述

此时,不管枚举类型啥的,前端传个String就行。最后,注解的依赖坐标引对:

在这里插入图片描述

5、补充:@ConstructorProperties

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

类加载过程

Java类加载过程包括加载&#xff08;Loading&#xff09;、验证&#xff08;Verification&#xff09;、准备&#xff08;Preparation&#xff09;、解析&#xff08;Resolution&#xff09;、初始化&#xff08;Initialization&#xff09;五个阶段。这些阶段是按照顺序逐步执…

5.3 Windows驱动开发:内核取应用层模块基址

在上一篇文章《内核取ntoskrnl模块基地址》中我们通过调用内核API函数获取到了内核进程ntoskrnl.exe的基址&#xff0c;当在某些场景中&#xff0c;我们不仅需要得到内核的基地址&#xff0c;也需要得到特定进程内某个模块的基地址&#xff0c;显然上篇文章中的方法是做不到的&…

【AI】行业消息精选和分析(11月23日)

今日动态 1、Sam Altman 重掌 CEO&#xff0c;OpenAI 权力斗争正式「落幕」 2、重磅好消息&#xff1a;语音 ChatGPT 现已向全用户开放 3、NVIDIA 与基因泰克合作&#xff0c;利用生成式 AI 加速药物发现 4、 英伟达Q3营收同比增长206%至181亿美元 黄仁勋&#xff1a;生成式AI时…

HarmonyOS ArkTS 应用添加弹窗(八)

概述 在我们日常使用应用的时候&#xff0c;可能会进行一些敏感的操作&#xff0c;比如删除联系人&#xff0c;这时候我们给应用添加弹窗来提示用户是否需要执行该操作&#xff0c;如下图所示&#xff1a; 弹窗是一种模态窗口&#xff0c;通常用来展示用户当前需要的或用户必须…

电商数据采集|电商API接口接入|从京东平台获取商品SKU 主图 价格 详情数据

在进行API开发过程中&#xff0c;数据异常常常令人头痛。我们的API开车软件经过精心设计和测试&#xff0c;能够准确识别并及时处理各类数据异常。拥有稳定的运行环境&#xff0c;保障了您的开发进程不受干扰&#xff0c;让您的工作更加顺畅高效。 京东获得JD商品详情 API 返…

如何判断交流回馈老化测试负载是否合格?

交流回馈老化测试负载是用于模拟实际工作环境中设备运行状态的测试工具&#xff0c;主要用于检测设备的耐久性和稳定性。 负载性能&#xff1a;需要检查负载的性能是否符合设计要求&#xff0c;这包括负载的功率、电流、电压等参数是否在规定的范围内&#xff0c;以及负载的工作…

信号功率放大器的工作原理和特点是什么

信号功率放大器是一种电子设备&#xff0c;用于将输入信号的功率进行放大&#xff0c;以达到所需的输出功率水平。它在各个领域中都有广泛的应用&#xff0c;包括音频放大器、射频放大器、激光功率放大器等。下面将详细介绍信号功率放大器的工作原理和特点。 工作原理&#xff…

什么是高防IP?如何进行防护?怎样隐藏源站?

高防IP是针对互联网服务器遭受大流量的DDoS攻击后导致服务不可用的情况下&#xff0c;推出的付费增值服务&#xff0c;是目前最常用的一种防御DDoS攻击的手段。用户在数据不转移的情况下&#xff0c;就可以通过配置高防IP&#xff0c;将攻击流量引流到高防IP&#xff0c;防护系…

redis-cluster集群

redis-cluster集群 redis3.0引入的分布式存储方案 集群由多个node节点组成&#xff0c;redis数据分布在这些节点之中 在集群之中分为主节点和从节点 集群模式当中&#xff0c;主从一一对应&#xff0c;数据写入和读取与主从模式一样&#xff0c;主负责写&#xff0c;从只能读…

echarts的横向柱状图文字省略,鼠标移入显示内容 vue3

效果图 文字省略 提示 如果是在x轴上的&#xff0c;就在x轴上添加triggerEvent: true,如果是y轴就在y轴添加&#xff0c;我是在y轴上添加的 并且自定义的方法&#xff08;我取名为extension&#xff09; // echarts 横向省略文字 鼠标移入显示内容 export const extension…

[MySQL-基础]SQL语句

目录 hello! 这里是欧_aita的频道。 今日语录: 只有放弃才是真正的失败。 祝福语&#xff1a;愿你的代码生活充满注释&#xff0c;逻辑清晰&#xff0c;debug之路畅通无阻。 大家可以在评论区畅所欲言&#xff0c;可以指出我的错误&#xff0c;在交流中共同进步。 欢迎关注我的…

基于 Modbus 的工业数据采集、控制(part 3)

Modbus 设备(利用 slave 模拟) Modbus 采集程序 client.c #include "client.h"modbus_t *ctx; key_t key_shm, key_msg; int shmid, msgid; struct shm *shm0; struct msgbuf msg0;void *collector(void *arg) {struct shm *p = (struct shm *)arg;while (1){sle…

目前比较好用的护眼台灯?央视公认好用的五款护眼台灯推荐

据国家卫健委最新数据&#xff0c;2020年我国儿童青少年总体近视率是52.7&#xff05;&#xff0c;幼儿园&#xff08;数据仅覆盖大班&#xff09;近视率达14.3&#xff05;&#xff0c;小学阶段35.6&#xff05;&#xff0c;初中阶段71.1&#xff05;&#xff0c;而高中阶段达…

运维 在Windows上搭建小型Git服务

文章目录 1、Git选型1.1、主要特性1.2、代码管理1.3、工单管理1.4、Pull/Merge requests1.5、第三方集成1.6、选型结论 2、环境搭建2.1、Gitea下载2.2、Gitea安装2.3、配置服务信息2.4、运行服务2.5、注册Gitea为服务2.6、正常使用 1、Git选型 1.1、主要特性 1.2、代码管理 1.…

创建vue项目体验

文章目录 使用vue-cli创建vue项目创建出的项目目录结构配置router 运行问题router未找到eslint报错 首页显示单页面内容替换 使用vue-cli创建vue项目 安装vue-cli&#xff0c;创建基本项目 选择步骤 一般创建成功后&#xff0c;提示使用下面的指令运行demo npm run serve创建…

发挥云计算潜力:Amazon Lightsail 与 Amazon EC2 的综述

文章作者&#xff1a;Libai 欢迎来到云计算世界&#xff0c;这里有无数的机会和无限的应用程序增长。 在当今的数字时代&#xff0c;企业可能会发现管理基础架构和扩展应用程序具有挑战性。 传统的本地解决方案需要大量的硬件、软件和维护前期投资。 要满足不断增长的需求&…

Vatee万腾数字引领未来:vatee科技力量的独特路径

在当今数字化浪潮的推动下&#xff0c;Vatee万腾以其卓越的科技力量&#xff0c;正引领着未来的数字化时代&#xff0c;描绘着一条独特的发展路径。通过持续创新、前瞻思维和对技术的深度理解&#xff0c;Vatee万腾正在为未来的科技发展创造新的可能性&#xff0c;塑造着数字引…

节能灯和led灯哪个更护眼?精选高品质的LED护眼台灯

节能灯和LED灯相比&#xff0c;我认为LED灯会更加护眼一些&#xff0c;不过想要更护眼建议选择LED的护眼台灯会更好&#xff01; 大家都知道光亮对于我们来说是非常重要的&#xff0c;尤其是夜晚的时候&#xff0c;往往要借助一些灯具来提供充足的照明。对于孩子而言&#xff0…

小型洗衣机哪个牌子好用又耐用?最好用的迷你洗衣机

随着大家工作的压力越来越大&#xff0c;下了班之后只能想躺平&#xff0c;在洗完澡之后看着还需要手洗的内衣裤真的很头疼。有些小伙伴还有会攒几天再丢进去洗衣机里面一起&#xff0c;而且这样子是非常不好的&#xff0c;用过的内衣裤长时间不清洗容易滋生细菌&#xff0c;而…

qq录屏怎么只录电脑声音?我来告诉你答案

录制屏幕已成为人们日常生活中经常需要使用的功能&#xff0c;尤其是录制电脑声音。qq作为国内最受欢迎的社交软件之一&#xff0c;其内置的录屏功能十分便捷&#xff0c;可以满足用户的基本需求。可是您知道qq录屏怎么只录电脑声音吗&#xff1f;在本文中&#xff0c;我们将详…