SpringBoot整合Jackson超详细用法(附Jackson工具类)

作者:陈老老老板 时间:2023-05-31 23:56:06 

一、Jackson简介

说明:本篇讲的是Jackson的详细用法,Jackson工具类在文章最后,直接复制粘贴即可使用。 Jackson是公司中必用的组件之一,常用的还用阿里的Fastjson,但是由于一些原因bug与漏洞是在是太多,在注重安全的公司直接被pass,还有就是谷歌的Gson(这个没用过不太了解)。 Spring MVC 的默认 json 解析器便是 Jackson。 Jackson 优点很多。 Jackson 所依赖的 jar 包较少 ,简单易用。与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快;Jackson 运行时占用内存比较低,性能比较好;Jackson 有灵活的 API,可以很容易进行扩展和定制。

额外了解:
Jackson 的 1.x 版本的包名是 org.codehaus.jackson
当升级到 2.x 版本时,包名变为com.fasterxml.jackson

Jackson 有三个核心包,分别是 StreamingDatabidAnnotations,通过这些包可以方便的对 JSON 进行操作.

  • jackson-core:核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。

  • jackson-annotations:注解包,提供标准注解功能.

  • jackson-databind :数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。包含上面两个包,只导入这个坐标即可。

运行环境:

  • idea2020.2

  • jdk1.8

  • springboot 2.7.9

下载demo:直接去我的资源下载即可(Jackson实例-附工具类)

二、Json简介

说明: 作为Java开发一定要学习Json,在现在的前后端分离的项目中,Json是最常见的数据交换格式。比如SpringBoot中@RequestBody注解就是作为接收Json格式的注解,在使用Postman进行测试时传输的raw-json也是Json格式数据。

JSON表示结构:
对象数组: 对象结构以”{”大括号开始,以”}”大括号结束,中间部分由0或多个以”,”分隔的”key(关键字)/value(值)”对构成,关键字和值之间以”:”分隔,语法结构如代码。这里给一个示例。

{
 "array": [1,2,3],
 "boolean": true,
 "name": "cllb",
 "null": null,
 "age": 12345,
 "object": {
   "height": 100,
   "color": "红色"
 },
 "string": "陈老老老板"
}

三、springboot整合Jackson

1.创建项目

说明: 创建一个空springboot项目(2.7.9版本)。这里就不过多复述了,创建时将lombok组件选上,十分方便无需再写Get/Set方法。
注意:可以看到导入databind包会自动导入剩下两个包。

SpringBoot整合Jackson超详细用法(附Jackson工具类)

2.导入坐标

说明: 可以看到导入databind包会自动导入剩下两个包。

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.13.3</version>
</dependency>

SpringBoot整合Jackson超详细用法(附Jackson工具类)

3.配置文件

a.配置文件配置

properties格式:

#指定日期格式,比如yyyy-MM-dd HH:mm:ss,或者具体的格式化类的全限定名
spring.jackson.date-format
#指定日期格式化时区,比如America/Los_Angeles或者GMT+10.
spring.jackson.time-zone
#是否开启Jackson的反序列化
spring.jackson.deserialization
#是否开启json的generators.
spring.jackson.generator
#指定Joda date/time的格式,比如yyyy-MM-ddHH:mm:ss). 如果没有配置的话,dateformat会作为backup
spring.jackson.joda-date-time-format
#指定json使用的Locale.
spring.jackson.locale
#是否开启Jackson通用的特性.
spring.jackson.mapper
#是否开启jackson的parser特性.
spring.jackson.parser
#指定PropertyNamingStrategy(CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES)或者指定PropertyNamingStrategy子类的全限定类名.
spring.jackson.property-naming-strategy
#是否开启jackson的序列化.
spring.jackson.serialization
#指定序列化时属性的inclusion方式,具体查看JsonInclude.Include枚举.
spring.jackson.serialization-inclusion

yml格式:

spring:
 jackson:
   #日期格式化
   date-format: yyyy-MM-dd HH:mm:ss
   time-zone: GMT+8
   #设置空如何序列化
   default-property-inclusion: non_null    
   serialization:
      #格式化输出
     indent_output: true
     #忽略无法转换的对象
     fail_on_empty_beans: false
   deserialization:
     #允许对象忽略json中不存在的属性
     fail_on_unknown_properties: false
   parser:
     #允许出现特殊字符和转义符
     allow_unquoted_control_chars: true
     #允许出现单引号
     allow_single_quotes: true

b.自定义配置

说明: 这里直接将Jackson工具类给大家,自定义配置指的就是工具类中,对于object_mapper的set赋值。什么方法都有,演示也直接使用工具类进行。

package com.clllb.jackson.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

@Slf4j
public class JacksonUtil {

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

private static final ObjectMapper OBJECT_MAPPER_SNAKE_CASE = new ObjectMapper();
   // 日期格式化
   private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";

static {
       //对象的所有字段全部列入
       OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.ALWAYS);
       //取消默认转换timestamps形式
       OBJECT_MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
       //忽略空Bean转json的错误
       OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
       //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss
       OBJECT_MAPPER.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
       //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
       OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
   }

static {
       //对象的所有字段全部列入
       OBJECT_MAPPER_SNAKE_CASE.setSerializationInclusion(JsonInclude.Include.ALWAYS);
       //取消默认转换timestamps形式
       OBJECT_MAPPER_SNAKE_CASE.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
       //忽略空Bean转json的错误
       OBJECT_MAPPER_SNAKE_CASE.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
       //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss
       OBJECT_MAPPER_SNAKE_CASE.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
       //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
       OBJECT_MAPPER_SNAKE_CASE.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
       //转换为下划线
       OBJECT_MAPPER_SNAKE_CASE.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
   }

private JacksonUtil() {
   }

/**
    * 对象转Json格式字符串
    *
    * @param obj 对象
    * @return Json格式字符串
    */
   public static <T> String obj2String(T obj) {
       if (obj == null) {
           return null;
       }
       try {
           return obj instanceof String ? (String) obj : OBJECT_MAPPER.writeValueAsString(obj);
       } catch (JsonProcessingException e) {
           log.warn("Parse Object to String error : {}", e.getMessage());
           return null;
       }
   }

/**
    * 对象转file
    * @param fileName
    * @param obj
    */
    public static void obj2File(String fileName,Object obj){
       if (obj == null){
           return;
       }
        try {
            OBJECT_MAPPER.writeValue(new File(fileName),obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

/**
    * 对象转Json格式字符串; 属性名从驼峰改为下划线形式
    *
    * @param obj 对象
    * @return Json格式字符串
    */
   public static <T> String obj2StringFieldSnakeCase(T obj) {
       if (obj == null) {
           return null;
       }
       try {
           ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;
           return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
       } catch (JsonProcessingException e) {
           log.warn("Parse Object to String error : {}", e.getMessage());
           return null;
       }
   }

/**
    * 字符串转换为自定义对象; 属性名从下划线形式改为驼峰
    *
    * @param str   要转换的字符串
    * @param clazz 自定义对象的class对象
    * @return 自定义对象
    */
   public static <T> T string2ObjFieldLowerCamelCase(String str, Class<T> clazz) {
       if (StringUtils.isEmpty(str) || clazz == null) {
           return null;
       }
       try {
           ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;
           return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
       } catch (Exception e) {
           log.warn("Parse String to Object error : {}", e.getMessage());
           return null;
       }
   }

/**
    * 字符串转换为自定义对象(List); 属性名从下划线形式改为驼峰
    *
    * @param str           要转换的字符串
    * @param typeReference 自定义对象的typeReference List 对象
    * @return 自定义对象
    */
   public static <T> List<T> string2ListFieldLowerCamelCase(String str, TypeReference<List<T>> typeReference) {
       if (StringUtils.isEmpty(str) || typeReference == null) {
           return null;
       }
       try {
           ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;
           return objectMapper.readValue(str, typeReference);
       } catch (Exception e) {
           log.warn("Parse String to Object error : {}", e.getMessage());
           return null;
       }
   }

/**
    * 对象转Json格式字符串(格式化的Json字符串)
    *
    * @param obj 对象
    * @return 美化的Json格式字符串
    */
   public static <T> String obj2StringPretty(T obj) {
       if (obj == null) {
           return null;
       }
       try {
           return obj instanceof String ? (String) obj : OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
       } catch (JsonProcessingException e) {
           log.warn("Parse Object to String error : {}", e.getMessage());
           return null;
       }
   }

/**
    * 字符串转换为自定义对象
    *
    * @param str   要转换的字符串
    * @param clazz 自定义对象的class对象
    * @return 自定义对象
    */
   public static <T> T string2Obj(String str, Class<T> clazz) {
       if (StringUtils.isEmpty(str) || clazz == null) {
           return null;
       }
       try {
           return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz);
       } catch (Exception e) {
           log.warn("Parse String to Object error : {}", e.getMessage());
           return null;
       }
   }

/**
    * 字符串转换为自定义字段转为list
    * @param str
    * @param typeReference
    * @param <T>
    * @return
    */
   public static <T> T string2Obj(String str, TypeReference<T> typeReference) {
       if (StringUtils.isEmpty(str) || typeReference == null) {
           return null;
       }
       try {
           return (T) (typeReference.getType().equals(String.class) ? str : OBJECT_MAPPER.readValue(str, typeReference));
       } catch (IOException e) {
           log.warn("Parse String to Object error", e);
           return null;
       }
   }

public static <T> T string2Obj(String str, Class<?> collectionClazz, Class<?>... elementClazzes) {
       JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClazz, elementClazzes);
       try {
           return OBJECT_MAPPER.readValue(str, javaType);
       } catch (IOException e) {
           log.warn("Parse String to Object error : {}" + e.getMessage());
           return null;
       }
   }
}

4.实体类

说明: 这里创建一个user实体类

package com.clllb.jackson.PO;

import lombok.Data;

import java.util.List;

@Data
public class User {

private String username;

private Integer age;

private List<String> info;

private Long userId;
}

项目样图:

SpringBoot整合Jackson超详细用法(附Jackson工具类)

5.测试类

说明: 测试类中直接调工具类中的方法,非常简单,附输出结果。

a.object类型转Json

说明: 使用writeValueAsString方法

@Test
   void obj2string(){
       User user = new User();
       user.setUsername("clllb");
       user.setAge(24);
       user.setUserId(1L);
       List<String> infoList = new ArrayList<>();
       infoList.add("有一百万");
       infoList.add("发大财");
       user.setInfo(infoList);

String json = JacksonUtil.obj2String(user);
       System.out.println(json);
   }

输出结果:

{"username":"clllb","age":24,"info":["有一百万","发大财"],"userId":1}

b.object类型转file

说明: 使用writeValue方法

@Test
   void obj2file(){
       User user = new User();
       user.setUsername("clllb");
       user.setAge(24);
       user.setUserId(1L);
       List<String> infoList = new ArrayList<>();
       infoList.add("有一百万");
       infoList.add("发大财");
       user.setInfo(infoList);
       String fileName = "ccccc";
       JacksonUtil.obj2File(fileName,user);
   }

输出结果:

SpringBoot整合Jackson超详细用法(附Jackson工具类)

c.string类型转Object自定义类型

说明: 使用readValue方法

@Test
   void string2obj(){
       String json = "{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"userId\":11}";
       User user = JacksonUtil.string2Obj(json, User.class);
       System.out.println(user);
   }

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)

d.string类型转Object自定义类型list

说明: 使用readValue方法,传参变为TypeReference typeReference,这里工具类用的重载方法名是相同的。

@Test
   void string2objList(){
       String json = "[{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"userId\":11},\n" +
               "{\"username\":\"陈老老老板\",\"age\":25,\"info\":[\"有一千万\",\"发大大财\"],\"userId\":12}]";
       List<User> user = JacksonUtil.string2Obj(json, new TypeReference<List<User>>(){});
       user.forEach(System.out::println);
   }

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)
User(username=陈老老老板, age=25, info=[有一千万, 发大大财], userId=12)

e.object类型转String(驼峰转下划线)

说明: 使用writeValueAsString方法,这里区别看工具类就会发现,就是多了一个设置OBJECT_MAPPER_SNAKE_CASE.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);

@Test
   void obj2sringSnakeCase(){
       User user = new User();
       user.setUsername("clllb");
       user.setAge(24);
       user.setUserId(11L);
       List<String> infoList = new ArrayList<>();
       infoList.add("有一百万");
       infoList.add("发大财");
       user.setInfo(infoList);
       String json = JacksonUtil.obj2StringFieldSnakeCase(user);
       System.out.println(json);
   }

输出结果:

{"username":"clllb","age":24,"info":["有一百万","发大财"],"user_id":11}

f.string类型(下划线)转Object类型

<font color = 'red'><b>说明:</font> 使用readValue方法
```java
@Test
   void string2obj(){
       String json = "{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"user_id\":11}";
       User user = JacksonUtil.string2Obj(json, User.class);
       System.out.println(user);
   }

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)

g.string类型(下划线)转Object自定义类型list

说明: 使用readValue方法,传参变为TypeReference typeReference,这里工具类用的重载方法名是相同的。

@Test
   void string2objSnakeCase(){
       String json = "[{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"user_id\":11},\n" +
               "{\"username\":\"陈老老老板\",\"age\":25,\"info\":[\"有一千万\",\"发大大财\"],\"user_id\":12}]";
       List<User> user = JacksonUtil.string2ListFieldLowerCamelCase(json, new TypeReference<List<User>>(){});
       user.forEach(System.out::println);
   }

输出结果:

User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)
User(username=陈老老老板, age=25, info=[有一千万, 发大大财], userId=12)

总结:工具类非常好用,包含日常所需。Jackson常见用法总结。希望对您有帮助,感谢阅读

来源:https://blog.csdn.net/weixin_47343544/article/details/129412730

标签:SpringBoot,Jackson
0
投稿

猜你喜欢

  • Android自定义View仿QQ运动步数效果

    2021-06-25 00:11:37
  • java jpa如何自定义sql语句

    2022-08-04 14:36:52
  • 如何在C#9 中使用static匿名函数

    2022-06-21 01:44:03
  • SpringBoot启动yaml报错的解决

    2021-09-09 22:58:14
  • android 获取上一个activity返回值的方法

    2023-06-15 13:22:22
  • Java线程池的优点及池化技术的应用

    2022-07-01 08:12:23
  • Java中MessageDigest来实现数据加密的方法

    2023-05-18 01:13:49
  • 详解App保活技术实现

    2023-05-24 18:06:26
  • Android项目实战手把手教你画圆形水波纹loadingview

    2023-03-15 10:13:47
  • SpringBoot2.x 集成 Thymeleaf的详细教程

    2021-07-31 18:18:23
  • 关于springboot2整合lettuce启动卡住问题的解决方法

    2022-08-24 09:29:16
  • C语言 auto和register关键字

    2021-11-03 02:40:54
  • C#中委托、事件和回调的使用及说明

    2023-08-13 01:00:24
  • C#服务器NFS共享文件夹搭建与上传图片文件的实现

    2023-01-31 01:19:49
  • Spring框架开发scope作用域分析总结

    2023-05-04 14:43:44
  • 基于C语言实现井字棋游戏

    2023-06-28 21:23:18
  • Android 7.0中新签名对多渠道打包的影响详解

    2023-09-02 12:30:18
  • Java 高并发八:NIO和AIO详解

    2023-01-29 15:50:51
  • java如何实现自动生成数据库设计文档

    2023-08-07 19:01:28
  • Android CardView详解及使用方法和实例

    2023-01-11 01:04:30
  • asp之家 软件编程 m.aspxhome.com