• springboot实战(七)之jackson配置前后端交互下划线转驼峰&对象序列化与反序列化


    目录

    环境:

    1.驼峰转下划线配置 

    1.1单个字段命名转化使用@JsonProperty注解

    1.2单个类进行命名转化

    3.全局命名策略配置

    2. 序列化以及反序列化

    2.1序列化

    2.2反序列化

    3.自定义序列化与反序列化 


    在Web开发中,JSON(JavaScript Object Notation)成为了一种广泛使用的前后端、服务端与服务端的交互的数据格式,主要用于前后端数据传输和存储。

    1.Java是一种面向对象编程语言,而JSON是一种键值对格式的数据,因此在Java中,需要将Java对象转换为JSON字符串,或者将JSON字符串转换为Java对象。这个过程就是JSON的序列化和反序列化。

    2.在生产过程中由于命名规范的问题,前后端交互往往使用的是下划线的方式进行出入参,而java项目中的实体类中的参数命名规则一般是小驼峰命名,所以在前后端交互过程中需要进行下划线转驼峰的配置。

    对于Java中的JSON序列化和反序列化,有很多开源库可供选择,其中Jackson库是最受欢迎的之一。Jackson库提供了丰富的功能,可以实现灵活的JSON序列化和反序列化,而且性能非常出色。

    环境:

    jdk:1.8

    springboot版本:2.7.15

    spingboot依赖中已经集成了Jackson相关依赖

    1.驼峰转下划线配置 

    jackson对驼峰转下划线配置有3个作用域的配置,分别是单个字段,单个类以及全局配置。

    1.1单个字段命名转化使用@JsonProperty注解

    首先我们创建一个UInfo实体类

    1. package com.iterge.iterge_pre.entity;
    2. import com.fasterxml.jackson.annotation.JsonProperty;
    3. import lombok.Data;
    4. /**
    5. * @author liuph
    6. * @date 2023/9/22 11:07:12
    7. */
    8. @Data
    9. public class UInfo {
    10. @JsonProperty("first_name")
    11. private String firstName;
    12. private String lastName;
    13. private Integer age;
    14. }

    接口返回测试:

    1. package com.iterge.iterge_pre.controller;
    2. import com.iterge.iterge_pre.entity.TUser;
    3. import com.iterge.iterge_pre.entity.UInfo;
    4. import org.springframework.web.bind.annotation.GetMapping;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.bind.annotation.RestController;
    7. /**
    8. *

    9. * 前端控制器
    10. *

    11. *
    12. * @author iterge
    13. * @since 2023-09-05
    14. */
    15. @RestController
    16. @RequestMapping("/tUser")
    17. public class TUserController {
    18. @GetMapping("test")
    19. public UInfo get(){
    20. UInfo uInfo = new UInfo();
    21. uInfo.setFirstName("san");
    22. uInfo.setLastName("zhang");
    23. uInfo.setAge(20);
    24. return uInfo;
    25. }
    26. }

    结果:

    1.2单个类进行命名转化

    使用@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)注解

    修改UInfo类:

    1. package com.iterge.iterge_pre.entity;
    2. import com.fasterxml.jackson.databind.PropertyNamingStrategies;
    3. import com.fasterxml.jackson.databind.annotation.JsonNaming;
    4. import lombok.Data;
    5. /**
    6. * @author liuph
    7. * @date 2023/9/22 11:07:12
    8. */
    9. @Data
    10. @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    11. public class UInfo {
    12. //@JsonProperty("first_name")
    13. private String firstName;
    14. private String lastName;
    15. private Integer age;
    16. }
    1. package com.iterge.iterge_pre.entity;
    2. import com.baomidou.mybatisplus.annotation.IdType;
    3. import com.baomidou.mybatisplus.annotation.TableId;
    4. import com.baomidou.mybatisplus.annotation.TableName;
    5. import java.io.Serializable;
    6. /**
    7. *

    8. *
    9. *

    10. *
    11. * @author iterge
    12. * @since 2023-09-05
    13. */
    14. @TableName("user_info")
    15. public class UserInfo implements Serializable {
    16. private static final long serialVersionUID = 1L;
    17. @TableId(value = "id", type = IdType.AUTO)
    18. private Long id;
    19. private String firstName;
    20. private String age;
    21. public Long getId() {
    22. return id;
    23. }
    24. public void setId(Long id) {
    25. this.id = id;
    26. }
    27. public String getFirstName() {
    28. return firstName;
    29. }
    30. public void setFirstName(String firstName) {
    31. this.firstName = firstName;
    32. }
    33. public String getAge() {
    34. return age;
    35. }
    36. public void setAge(String age) {
    37. this.age = age;
    38. }
    39. @Override
    40. public String toString() {
    41. return "UserInfo{" +
    42. "id = " + id +
    43. ", firstName = " + firstName +
    44. ", age = " + age +
    45. "}";
    46. }
    47. }

    接口测试结果:

    上面两图可以观察到UInfo输出是下划线,而UserInfo还是驼峰。

    3.全局命名策略配置

    全局命名策略配置5种,需要在yml文件中设置spring.jackson.property-naming-strategy: SNAKE_CASE

    命名策略描述
    策略例子备注
    LOWER_CAMEL_CASEfirstName默认策略 小驼峰命名
    UPPER_CAMEL_CASEFirstName大驼峰命名
    KEBAB_CASEfirst-name短横线命名
    LOWER_CASEfirstname全小写命名
    SNAKE_CASEfirst_name下划线命名

    配置:

    1. spring:
    2. profiles:
    3. active: dev
    4. jackson:
    5. property-naming-strategy: SNAKE_CASE
    6. mybatis-plus:
    7. configuration:
    8. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    9. #mapper-locations: classpath:mapper/*Mapper.xml

    修改UInfo类,注释@JsonNaming:

    1. package com.iterge.iterge_pre.entity;
    2. import com.fasterxml.jackson.databind.PropertyNamingStrategies;
    3. import com.fasterxml.jackson.databind.annotation.JsonNaming;
    4. import lombok.Data;
    5. /**
    6. * @author liuph
    7. * @date 2023/9/22 11:07:12
    8. */
    9. @Data
    10. //@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    11. public class UInfo {
    12. //@JsonProperty("first_name")
    13. private String firstName;
    14. private String lastName;
    15. private Integer age;
    16. }

    测试结果:

    由图可知两个接口输出都改成了“_”下划线的格式输出

    2. 序列化以及反序列化

    2.1序列化

    将Java对象转换为JSON字符串最基本的方法就是使用​​ObjectMapper​​​类的​​writeValueAsString​​方法。这个方法接收一个Java对象作为参数,返回一个JSON字符串。

    序列化和反序列化也可以使用阿里开源的fastjson,使用教程:fastjson详解

    1. package com.iterge.iterge_pre.mapper;
    2. import com.fasterxml.jackson.databind.ObjectMapper;
    3. import com.iterge.iterge_pre.entity.UInfo;
    4. import lombok.SneakyThrows;
    5. import org.junit.jupiter.api.Test;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. /**
    8. * @author liuph
    9. * @date 2023/9/22 11:09:15
    10. */
    11. @SpringBootTest
    12. public class JacksonTest {
    13. ObjectMapper mapper = new ObjectMapper();
    14. @SneakyThrows
    15. @Test
    16. public void test1(){
    17. UInfo uInfo = new UInfo();
    18. uInfo.setFirstName("san");
    19. uInfo.setLastName("zhang");
    20. uInfo.setAge(20);
    21. System.out.println(mapper.writeValueAsString(uInfo));
    22. }
    23. }

    2.2反序列化

    将JSON字符串转换为Java对象的基本方法是使用​​ObjectMapper​​​类的​​readValue​​方法。这个方法接收两个参数:一个JSON字符串和一个Java类,它会将JSON字符串反序列化为指定的Java类对象。 

    1. package com.iterge.iterge_pre.mapper;
    2. import com.fasterxml.jackson.databind.ObjectMapper;
    3. import com.iterge.iterge_pre.entity.UInfo;
    4. import lombok.SneakyThrows;
    5. import lombok.extern.slf4j.Slf4j;
    6. import org.junit.jupiter.api.Test;
    7. import org.springframework.boot.test.context.SpringBootTest;
    8. /**
    9. * @author liuph
    10. * @date 2023/9/22 11:09:15
    11. */
    12. @SpringBootTest
    13. @Slf4j
    14. public class JacksonTest {
    15. ObjectMapper mapper = new ObjectMapper();
    16. @SneakyThrows
    17. @Test
    18. public void test1(){
    19. UInfo uInfo = new UInfo();
    20. uInfo.setFirstName("san");
    21. uInfo.setLastName("zhang");
    22. uInfo.setAge(20);
    23. System.out.println(mapper.writeValueAsString(uInfo));
    24. }
    25. @SneakyThrows
    26. @Test
    27. public void test2(){
    28. String str = "{\"firstName\":\"san\",\"lastName\":\"zhang\",\"age\":20}";
    29. UInfo uInfo = mapper.readValue(str, UInfo.class);
    30. log.info("first name:{}",uInfo.getFirstName());
    31. }
    32. }

    3.自定义序列化与反序列化 

    在某些情况下,Jackson库提供的默认序列化和反序列化行为可能无法满足需求,需要自定义序列化和反序列化规则。例如,在序列化​​UInfo对象时,我们希望将年龄按字符串类型序列化,而不是默认的整型类型。

     新建序列化方法IntToStringSerializer

    1. package com.iterge.iterge_pre.config;
    2. import com.fasterxml.jackson.core.JsonGenerator;
    3. import com.fasterxml.jackson.databind.JsonSerializer;
    4. import com.fasterxml.jackson.databind.SerializerProvider;
    5. import java.io.IOException;
    6. /**
    7. * @author liuph
    8. * @date 2023/9/22 14:17:07
    9. */
    10. public class IntToStringSerializer extends JsonSerializer {
    11. @Override
    12. public void serialize(Integer integer, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
    13. jsonGenerator.writeString(integer.toString());
    14. }
    15. }

    对UInfo对象age字段添加注解@JsonSerialize(using = IntToStringSerializer.class)

    1. package com.iterge.iterge_pre.entity;
    2. import com.fasterxml.jackson.databind.PropertyNamingStrategies;
    3. import com.fasterxml.jackson.databind.annotation.JsonNaming;
    4. import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    5. import com.iterge.iterge_pre.config.IntToStringSerializer;
    6. import lombok.Data;
    7. /**
    8. * @author liuph
    9. * @date 2023/9/22 11:07:12
    10. */
    11. @Data
    12. //@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    13. public class UInfo {
    14. //@JsonProperty("first_name")
    15. private String firstName;
    16. private String lastName;
    17. @JsonSerialize(using = IntToStringSerializer.class)
    18. private Integer age;
    19. }

    测试:

  • 相关阅读:
    防火墙实验一
    Android9.0 mtk录像流程分析
    js中的设计模式之适配器模式
    1000套web前端期末大作业 HTML+CSS+JavaScript网页设计实例 企业网站制作【建议收藏】
    7.Python_结构型模式_桥模式
    Nacos服务发现与注册中心之服务消费(发现)者(客户端源码)
    若依分割拼接图片地址
    Vue3+TS中的shims-vue.d.ts文件的作用及代码说明
    layui tree监控选中事件,同步选中和取消
    力扣(LeetCode)算法_C++——移位字符串分组
  • 原文地址:https://blog.csdn.net/it_erge/article/details/133161590