javascript
《SpringBoot篇》26.SpringBoot整合Jackson超详细教程(附Jackson工具类)
👨?💻本文簡述:本文講一下Jackson常見用法,超級詳細。
👨?💻上一篇文章: 《SpringBoot篇》25.SpringBoot整合ActiveMQ
👨?💻有任何問題,都可以私聊我,我能幫得上的一定幫忙,感謝大佬們支持。
🦹我認為人人都可以學好編程,我愿意成為你的領路人!(需內推私聊)
一、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 有三個核心包,分別是 Streaming、Databid、Annotations,通過這些包可以方便的對 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(值)”對構成,關鍵字和值之間以”:”分隔,語法結構如代碼。這里給一個示例。
三、springboot整合Jackson
1.創建項目
說明: 創建一個空springboot項目(2.7.9版本)。這里就不過多復述了,創建時將lombok組件選上,十分方便無需再寫Get/Set方法。
注意:可以看到導入databind包會自動導入剩下兩個包。
2.導入坐標
說明: 可以看到導入databind包會自動導入剩下兩個包。
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.3</version> </dependency>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-inclusionyml格式:
spring:jackson:#日期格式化date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8#設置空如何序列化default-property-inclusion: non_null serialization:#格式化輸出 indent_output: true#忽略無法轉換的對象fail_on_empty_beans: falsedeserialization:#允許對象忽略json中不存在的屬性fail_on_unknown_properties: falseparser:#允許出現特殊字符和轉義符allow_unquoted_control_chars: true#允許出現單引號allow_single_quotes: trueb.自定義配置
說明: 這里直接將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:ssOBJECT_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:ssOBJECT_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; }項目樣圖:
5.測試類
說明: 測試類中直接調工具類中的方法,非常簡單,附輸出結果。
a.object類型轉Json
說明: 使用writeValueAsString方法
@Testvoid 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方法
@Testvoid 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);}輸出結果:
c.string類型轉Object自定義類型
說明: 使用readValue方法
@Testvoid 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,這里工具類用的重載方法名是相同的。
@Testvoid 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);
@Testvoid 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@Testvoid 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,這里工具類用的重載方法名是相同的。
@Testvoid 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常見用法總結。希望對您有幫助,感謝閱讀
結束語:裸體一旦成為藝術,便是最圣潔的。道德一旦淪為虛偽,便是最下流的。
勇敢去做你認為正確的事,不要被世俗的流言蜚語所困擾。
總結
以上是生活随笔為你收集整理的《SpringBoot篇》26.SpringBoot整合Jackson超详细教程(附Jackson工具类)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 易维帮助台:从细节升级优化彰显服务品质
- 下一篇: SpringBoot学习笔记~狂神