Java中對(duì)象?和?json?互轉(zhuǎn)四種方式?json-lib、Gson、FastJson、Jackson
一、 json-lib
json-lib最開(kāi)始的也是應(yīng)用最廣泛的json解析工具,json-lib 不好的地方確實(shí)是依賴于很多第三方包,
包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,
對(duì)于復(fù)雜類(lèi)型的轉(zhuǎn)換,json-lib對(duì)于json轉(zhuǎn)換成bean還有缺陷,比如一個(gè)類(lèi)里面會(huì)出現(xiàn)另一個(gè)類(lèi)的list或者map集合,json-lib從json到bean的轉(zhuǎn)換就會(huì)出現(xiàn)問(wèn)題。
json-lib在功能和性能上面都不能滿足現(xiàn)在互聯(lián)網(wǎng)化的需求。
二、 Google的Gson
1.簡(jiǎn)介
(1)Gson是目前功能最全的Json解析神器,Gson當(dāng)初是為因應(yīng)Google公司內(nèi)部需求而由Google自行研發(fā)而來(lái) 但自從在2008年五月公開(kāi)發(fā)布第一版后已被許多公司或用戶應(yīng)用。
Gson的應(yīng)用主要為toJson與fromJson兩個(gè)轉(zhuǎn)換函數(shù),無(wú)依賴,不需要例外額外的jar,能夠直接跑在JDK上。
而在使用這種對(duì)象轉(zhuǎn)換之前需先創(chuàng)建好對(duì)象的類(lèi)型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對(duì)應(yīng)的對(duì)象。
類(lèi)里面只要有g(shù)et和set方法,Gson完全可以將復(fù)雜類(lèi)型的json到bean或bean到j(luò)son的轉(zhuǎn)換,是JSON解析的神器。
Gson在功能上面無(wú)可挑剔,但是性能上面比FastJson有所差距。
(2)默認(rèn)是不序列化null值對(duì)應(yīng)的key的,具體案例如下:
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
AutoPartsSearchRequest request = new AutoPartsSearchRequest();
request.setKeywords("123");
request.setSortingField("234242");
Gson g = new GsonBuilder().create();
String str = g.toJson(request);
System.out.println(str);
//輸出結(jié)果:{"sortingField":"234242","keywords":"123"}
}若是想序列化null值對(duì)應(yīng)的key,只需要將以上創(chuàng)建代碼改成以下代碼就行:
Gson g = new GsonBuilder().serializeNulls().create();
若是想轉(zhuǎn)行null為空字符串"",則需要手動(dòng)處理了
(3)主要類(lèi)介紹
Gson類(lèi):解析json的最基礎(chǔ)的工具類(lèi)
JsonParser類(lèi):解析器來(lái)解析JSON到JsonElements的解析樹(shù)
JsonElement類(lèi):一個(gè)類(lèi)代表的JSON元素
JsonObject類(lèi):JSON對(duì)象類(lèi)型
JsonArray類(lèi):JsonObject數(shù)組
TypeToken類(lèi):用于創(chuàng)建type,比如泛型List<?>
(4)bean轉(zhuǎn)換json
Gson gson = new Gson(); String json = gson.toJson(obj); //obj是對(duì)象
(5) json轉(zhuǎn)換bean
Gson gson = new Gson();
String json = "{\"id\":\"2\",\"name\":\"Json技術(shù)\"}";
Book book = gson.fromJson(json, Book.class);(6) json轉(zhuǎn)換復(fù)雜的bean,比如List,Set
將json轉(zhuǎn)換成復(fù)雜類(lèi)型的bean,需要使用TypeToken
Gson gson = new Gson();
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
//將json轉(zhuǎn)換成List
List list = gson.fromJson(json,new TypeToken<LIST>() {}.getType());
//將json轉(zhuǎn)換成Set
Set set = gson.fromJson(json,new TypeToken<SET>() {}.getType());(7) 通過(guò)json對(duì)象直接操作json以及一些json的工具
a) 格式化Json
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(json);
json = gson.toJson(je);b) 判斷字符串是否是json,通過(guò)捕捉的異常來(lái)判斷是否是json
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
boolean jsonFlag;
try {
new JsonParser().parse(str).getAsJsonObject();
jsonFlag = true;
} catch (Exception e) {
jsonFlag = false;
}c) 從json串中獲取屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'id';
String propertyValue = "";
try {
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
propertyValue = jsonObj.get(propertyName).toString();
} catch (Exception e) {
propertyValue = null;
}d) 除去json中的某個(gè)屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'id';
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.remove(propertyName);
json = jsonObj.toString();e) 向json中添加屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'desc';
Object propertyValue = "json各種技術(shù)的調(diào)研";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue));
json = jsonObj.toString();f) 修改json中的屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'name';
Object propertyValue = "json各種技術(shù)的調(diào)研";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.remove(propertyName);
jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue));
json = jsonObj.toString();g) 判斷json中是否有屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'name';
boolean isContains = false ;
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
isContains = jsonObj.has(propertyName);h) json中日期格式的處理
GsonBuilder builder = new GsonBuilder();
builder.setDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Gson gson = builder.create();然后使用gson對(duì)象進(jìn)行json的處理,如果出現(xiàn)日期Date類(lèi)的對(duì)象,就會(huì)按照設(shè)置的格式進(jìn)行處理
i) json中對(duì)于Html的轉(zhuǎn)義
Gson gson = new Gson();
這種對(duì)象默認(rèn)對(duì)Html進(jìn)行轉(zhuǎn)義,如果不想轉(zhuǎn)義使用下面的方法
GsonBuilder builder = new GsonBuilder(); builder.disableHtmlEscaping(); Gson gson = builder.create();
2. 配置步驟
1. MAVEN 依賴引入
<!--gson-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>2. gsonUtil 工具類(lèi)
package com.dechnic.common.util;
import com.dechnic.common.anno.gson.Exclude;
import com.dechnic.common.po.ObjectTypeAdapter;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @description:
* @author:houqd
* @time: 2022/6/27 17:31
*/
public class GsonUtll {
private static Gson gson;
static {
ExclusionStrategy strategy = new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(Exclude.class) !=null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
};
gson = new GsonBuilder().disableHtmlEscaping().setExclusionStrategies(strategy).registerTypeAdapter(new TypeToken<Map<String,Object>>(){}.getType(),new ObjectTypeAdapter()).serializeNulls().create();
}
public static Map<String,Object> jsonStr2Map(String jsonStr){
return gson.fromJson(jsonStr, new TypeToken<Map<String, Object>>() {
}.getType());
}
public static List<Map<String,Object>> jsonStr2ListMap(String jsonStr){
return gson.fromJson(jsonStr, new TypeToken<List<Map<String, Object>>>() {
}.getType());
}
public static String toJSON(Object object){
return gson.toJson(object);
}
public static <T> List<T> json2ListBean(String result, Class<T> t){
List list = gson.fromJson(result, new TypeToken<List>() {
}.getType());
List list2 = new ArrayList();
for (Object o : list) {
list2.add(json2Bean(toJSON(o),t));
}
return list2;
}
public static <T> T json2Bean(String result,Class<T>t){
return gson.fromJson(result, t);
}
}3. 排除不要序列化的熟悉注解類(lèi) Exclude
package com.dechnic.common.anno.gson;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Exclude {
}三. 阿里巴巴的FastJson
1.簡(jiǎn)介
(1)Fastjson是一個(gè)Java語(yǔ)言編寫(xiě)的高性能的JSON處理器,由阿里巴巴公司開(kāi)發(fā)。
無(wú)依賴,不需要例外額外的jar,能夠直接跑在JDK上。
FastJson在復(fù)雜類(lèi)型的Bean轉(zhuǎn)換Json上會(huì)出現(xiàn)一些問(wèn)題,可能會(huì)出現(xiàn)引用的類(lèi)型,導(dǎo)致Json轉(zhuǎn)換出錯(cuò),需要制定引用。
FastJson采用獨(dú)創(chuàng)的算法,將parse的速度提升到極致,超過(guò)所有json庫(kù)。
(2)fastJson在轉(zhuǎn)換java對(duì)象為json的時(shí)候,默認(rèn)是不序列化null值對(duì)應(yīng)的key的,也就是說(shuō)當(dāng)對(duì)象里面的屬性為空的時(shí)候,在轉(zhuǎn)換成json時(shí),不序列化那些為null值的屬性
但是如果想把null對(duì)應(yīng)的key序列化出來(lái)呢?
那就要仔細(xì)看看fastjson轉(zhuǎn)換java對(duì)象為json的時(shí)候的入?yún)⒘耍阂簿褪沁@個(gè)方法:
JSONObject.toJSONString(Object object, SerializerFeature… features)
Fastjson的SerializerFeature序列化屬性:
QuoteFieldNames———-輸出key時(shí)是否使用雙引號(hào),默認(rèn)為true WriteMapNullValue——–是否輸出值為null的字段,默認(rèn)為false WriteNullNumberAsZero—-數(shù)值字段如果為null,輸出為0,而非null WriteNullListAsEmpty—–List字段如果為null,輸出為[],而非null WriteNullStringAsEmpty—字符類(lèi)型字段如果為null,輸出為”“,而非null WriteNullBooleanAsFalse–Boolean字段如果為null,輸出為false,而非null
結(jié)合上面,SerializerFeature… features是個(gè)數(shù)組,那么我們可以傳入我們想要的參數(shù),比如想序列化null,案例如下:
public static void main(String[] args) {
AutoPartsSearchRequest request = new AutoPartsSearchRequest();
request.setKeywords("123");
request.setSortingField("234242");
String str = JSONObject.toJSONString(request, SerializerFeature.WriteMapNullValue);
System.out.println(str);
}(3) bean轉(zhuǎn)換json將對(duì)象轉(zhuǎn)換成格式化的json
JSON.toJSONString(obj,true);
(4)將對(duì)象轉(zhuǎn)換成非格式化的json
JSON.toJSONString(obj,false);
obj設(shè)計(jì)對(duì)象
對(duì)于復(fù)雜類(lèi)型的轉(zhuǎn)換,對(duì)于重復(fù)的引用在轉(zhuǎn)成json串后在json串中出現(xiàn)引用的字符,比如 ref":"[0].books[1]
Student stu = new Student(); Set books= new HashSet(); Book book = new Book(); books.add(book); stu.setBooks(books); List list = new ArrayList(); for(int i=0;i<5;i++) list.add(stu); String json = JSON.toJSONString(list,true);
(5) json轉(zhuǎn)換bean
String json = "{\"id\":\"2\",\"name\":\"Json技術(shù)\"}";
Book book = JSON.parseObject(json, Book.class);(6) json轉(zhuǎn)換復(fù)雜的bean,比如List,Map
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
//將json轉(zhuǎn)換成List
List list = JSON.parseObject(json,new TypeReference<ARRAYLIST>(){});
//將json轉(zhuǎn)換成Set
Set set = JSON.parseObject(json,new TypeReference<HASHSET>(){});(7)通過(guò)json對(duì)象直接操作json
a) 從json串中獲取屬性
String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
propertyValue = obj.get(propertyName));b) 除去json中的某個(gè)屬性
String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
propertyValue = set.remove(propertyName);
json = obj.toString();c) 向json中添加屬性
String propertyName = 'desc';
Object propertyValue = "json的玩意兒";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
obj.put(propertyName, JSON.toJSONString(propertyValue));
json = obj.toString();d) 修改json中的屬性
String propertyName = 'name';
Object propertyValue = "json的玩意兒";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
if(set.contains(propertyName))
obj.put(propertyName, JSON.toJSONString(propertyValue));
json = obj.toString();e) 判斷json中是否有屬性
String propertyName = 'name';
boolean isContain = false;
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
isContain = set.contains(propertyName);f) json中日期格式的處理
Object obj = new Date(); String json = JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss.SSS");
簡(jiǎn)單的使用場(chǎng)景:
2.配置步驟
1.引入maven
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>2. 配置 CustomFastjsonConfig
package com.example.demo2.config;/**
* @className: WebMvcConfig
* @author: houqd
* @date: 2022/11/4
**/
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author:houqd
* @time: 2022/11/4 13:55
*/
@Configuration
public class CustomFastjsonConfig {
@Bean
public FastJsonHttpMessageConverter fastjsonHttpMessageConverters() {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setCharset(Charset.forName("UTF-8"));
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
//設(shè)置序列化特征
SerializerFeature[] serializerFeatures = new SerializerFeature[]{
//WriteNullStringAsEmpty: 如果字符串等于 null,那么會(huì)被序列化成空字符串 ""
SerializerFeature.WriteNonStringKeyAsString,
// WriteNullNumberAsZero: 如果數(shù)字等于 null,那么會(huì)被序列化成 0
SerializerFeature.WriteNullNumberAsZero,
// WriteNullBooleanAsFalse: 如果布爾類(lèi)型等于 null,那么會(huì)被序列化成 false
SerializerFeature.WriteNullBooleanAsFalse,
// PrettyFormat: 美化JSON
SerializerFeature.PrettyFormat
};
fastJsonConfig.setSerializerFeatures(serializerFeatures);
// 配置添加到消息轉(zhuǎn)換器里面
converter.setFastJsonConfig(fastJsonConfig);
converter.setDefaultCharset(Charset.forName("UTF-8"));
// 設(shè)置響應(yīng)JSON格式數(shù)據(jù)
List<MediaType> mediaTypeList = new ArrayList<>();
mediaTypeList.add(MediaType.APPLICATION_JSON);
// 設(shè)置消息轉(zhuǎn)換器支持的格式
converter.setSupportedMediaTypes(mediaTypeList);
return converter;
}
}3. 測(cè)試
User.java
package com.example.demo2.entity;/**
* @className: User
* @author: houqd
* @date: 2022/11/4
**/
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
*@description:
*@author:houqd
*@time: 2022/11/4 14:12
*
*/
@Data
public class User implements Serializable {
private String username;
private Date createTime;
private Boolean enabled;
private Integer num;
}
package com.example.demo2.entity;/**
* @className: User
* @author: houqd
* @date: 2022/11/4
**/
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
*@description:
*@author:houqd
*@time: 2022/11/4 14:12
*
*/
@Data
public class User implements Serializable {
private String username;
private Date createTime;
private Boolean enabled;
private Integer num;
}TestController.java
package com.example.demo2.controller;/**
* @className: TestController
* @author: houqd
* @date: 2022/11/4
**/
import com.example.demo2.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
*@description:
*@author:houqd
*@time: 2022/11/4 14:13
*
*/
@RestController
@RequestMapping("/api")
public class TestController {
@GetMapping("/json")
public List<User> json() {
List<User> list = this.getUserList();
return list;
}
// 模擬數(shù)據(jù)
private List<User> getUserList() {
List<User> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
User user = new User();
if (i != 1) {
user.setUsername("test-00" + i);
user.setCreateTime(new Date());
user.setEnabled(true);
user.setNum(520);
}
list.add(user);
}
return list;
}
}測(cè)試結(jié)果:

注意: fastJson 引用2.0.17 版本后 日期格式話失敗,退回到1.2.83 版本后正常。
4. 開(kāi)源的Jackson 簡(jiǎn)介:
(1)相比json-lib框架,Jackson所依賴的jar包較少,簡(jiǎn)單易用并且性能也要相對(duì)高些。
而且Jackson社區(qū)相對(duì)比較活躍,更新速度也比較快。
Jackson對(duì)于復(fù)雜類(lèi)型的json轉(zhuǎn)換bean會(huì)出現(xiàn)問(wèn)題,一些集合Map,List的轉(zhuǎn)換出現(xiàn)問(wèn)題。
Jackson對(duì)于復(fù)雜類(lèi)型的bean轉(zhuǎn)換Json,轉(zhuǎn)換的json格式不是標(biāo)準(zhǔn)的Json格式
(2)jackson默認(rèn)是序列化null對(duì)應(yīng)的key的,也就是說(shuō)不管你對(duì)象屬性有沒(méi)有值,在轉(zhuǎn)換json的時(shí)候都會(huì)被序列化出來(lái)
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
AutoPartsSearchRequest request = new AutoPartsSearchRequest();
request.setKeywords("123");
request.setSortingField("234242");
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(request);
System.out.println(str);
//輸出結(jié)果(此處就不格式化了):{"sortingField":"234242","partsClassifyId":null,"partsSubClassifyId":null,"sortingDirection":null:......
}2、同理,想要不序列化null也是可以的,具體如下:
1.實(shí)體上 @JsonInclude(Include.NON_NULL) //將該標(biāo)記放在屬性上,如果該屬性為NULL則不參與序列化 //如果放在類(lèi)上邊,那對(duì)這個(gè)類(lèi)的全部屬性起作用 //Include.Include.ALWAYS 默認(rèn) //Include.NON_DEFAULT 屬性為默認(rèn)值不序列化 //Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化 //Include.NON_NULL 屬性為NULL 不序列化 2.代碼上 ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_NULL); //通過(guò)該方法對(duì)mapper對(duì)象進(jìn)行設(shè)置,所有序列化的對(duì)象都將按改規(guī)則進(jìn)行系列化 //Include.Include.ALWAYS 默認(rèn) //Include.NON_DEFAULT 屬性為默認(rèn)值不序列化 //Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化 //Include.NON_NULL 屬性為NULL 不序列化
注意:只對(duì)VO起作用,Map List不起作用,另外jackson還能過(guò)濾掉你設(shè)置的屬性,具體的就各位自己去研究源碼了
(3)pringboot默認(rèn)使用Jackson ,@RestController注解,會(huì)采用HttpMessageConverter將數(shù)據(jù)進(jìn)行轉(zhuǎn)換后寫(xiě)入Response的body數(shù)據(jù)區(qū)
Jackson配置
引入maven
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.0</version>
</dependency>1. 通過(guò)在application.yml中進(jìn)行jackson的對(duì)應(yīng)配置去實(shí)現(xiàn)
spring:
jackson:
# 設(shè)置屬性命名策略,對(duì)應(yīng)jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json駝峰式轉(zhuǎn)下劃線,json body下劃線傳到后端自動(dòng)轉(zhuǎn)駝峰式
property-naming-strategy: SNAKE_CASE
# 全局設(shè)置@JsonFormat的格式pattern
date-format: yyyy-MM-dd HH:mm:ss
# 當(dāng)?shù)貢r(shí)區(qū)
locale: zh
# 設(shè)置全局時(shí)區(qū)
time-zone: GMT+8
# 常用,全局設(shè)置pojo或被@JsonInclude注解的屬性的序列化方式
default-property-inclusion: NON_NULL #不為空的屬性才會(huì)序列化,具體屬性可看JsonInclude.Include
# 常規(guī)默認(rèn),枚舉類(lèi)SerializationFeature中的枚舉屬性為key,值為boolean設(shè)置jackson序列化特性,具體key請(qǐng)看SerializationFeature源碼
serialization:
WRITE_DATES_AS_TIMESTAMPS: true # 返回的java.util.date轉(zhuǎn)換成timestamp
FAIL_ON_EMPTY_BEANS: true # 對(duì)象為空時(shí)是否報(bào)錯(cuò),默認(rèn)true
# 枚舉類(lèi)DeserializationFeature中的枚舉屬性為key,值為boolean設(shè)置jackson反序列化特性,具體key請(qǐng)看DeserializationFeature源碼
deserialization:
# 常用,json中含pojo不存在屬性時(shí)是否失敗報(bào)錯(cuò),默認(rèn)true
FAIL_ON_UNKNOWN_PROPERTIES: false
# 枚舉類(lèi)MapperFeature中的枚舉屬性為key,值為boolean設(shè)置jackson ObjectMapper特性
# ObjectMapper在jackson中負(fù)責(zé)json的讀寫(xiě)、json與pojo的互轉(zhuǎn)、json tree的互轉(zhuǎn),具體特性請(qǐng)看MapperFeature,常規(guī)默認(rèn)即可
mapper:
# 使用getter取代setter探測(cè)屬性,如類(lèi)中含getName()但不包含name屬性與setName(),傳輸?shù)膙o json格式模板中依舊含name屬性
USE_GETTERS_AS_SETTERS: true #默認(rèn)false
# 枚舉類(lèi)JsonParser.Feature枚舉類(lèi)中的枚舉屬性為key,值為boolean設(shè)置jackson JsonParser特性
# JsonParser在jackson中負(fù)責(zé)json內(nèi)容的讀取,具體特性請(qǐng)看JsonParser.Feature,一般無(wú)需設(shè)置默認(rèn)即可
parser:
ALLOW_SINGLE_QUOTES: true # 是否允許出現(xiàn)單引號(hào),默認(rèn)false
# 枚舉類(lèi)JsonGenerator.Feature枚舉類(lèi)中的枚舉屬性為key,值為boolean設(shè)置jackson JsonGenerator特性,一般無(wú)需設(shè)置默認(rèn)即可
# JsonGenerator在jackson中負(fù)責(zé)編寫(xiě)json內(nèi)容,具體特性請(qǐng)看JsonGenerator.Feature2.通過(guò)ObjectMapper 進(jìn)行代碼配置實(shí)現(xiàn)
/**
* 全局序列化配置類(lèi)
*/
@Configuration
public class JsonConfig {
/**
* 創(chuàng)建Jackson對(duì)象映射器
*
* @param builder Jackson對(duì)象映射器構(gòu)建器
* @return ObjectMapper
*/
@Bean
public ObjectMapper getJacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
//序列換成json時(shí),將所有的long變成string.因?yàn)閖s中得數(shù)字類(lèi)型不能包含所有的java long值,超過(guò)16位后會(huì)出現(xiàn)精度丟失
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
//反序列化的時(shí)候如果多了其他屬性,不拋出異常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//日期格式處理
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return objectMapper;
}
}方式二、重寫(xiě)configureMessageConverters方法
/**
* 全局序列化配置類(lèi)
*/
@Configuration
@EnableWebMvc
public class JsonConfig implements WebMvcConfigurer {
/**
* 全局序列化方式
*
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//Jackson的全局序列化方式
configureJacksonHttpMessageConverter(converters);
}
/**
* Jackson的全局序列化方式
*
* @param converters
*/
private void configureJacksonHttpMessageConverter(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
//序列換成json時(shí),將所有的long變成string.因?yàn)閖s中得數(shù)字類(lèi)型不能包含所有的java long值,超過(guò)16位后會(huì)出現(xiàn)精度丟失
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
//反序列化的時(shí)候如果多了其他屬性,不拋出異常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//日期格式處理
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
converter.setObjectMapper(objectMapper);
converters.add(converter);
converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
}
}ObjectMapper 常用工具類(lèi)
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Jackson 工具類(lèi)
* <p>Title: MapperUtils</p>
* <p>Description: </p>
*
*/
public class MapperUtils {
private final static ObjectMapper objectMapper = new ObjectMapper();
public static ObjectMapper getInstance() {
return objectMapper;
}
/**
* 轉(zhuǎn)換為 JSON 字符串
*
* @param obj
* @return
* @throws Exception
*/
public static String obj2json(Object obj) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
return mapper.writeValueAsString(obj);
}
/**
* 轉(zhuǎn)換為 JSON 字符串,忽略空值
*
* @param obj
* @return
* @throws Exception
*/
public static String obj2jsonIgnoreNull(Object obj) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.writeValueAsString(obj);
}
/**
* 轉(zhuǎn)換為 JavaBean
*
* @param jsonString
* @param clazz
* @return
* @throws Exception
*/
public static <T> T json2pojo(String jsonString, Class<T> clazz) throws Exception {
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
return objectMapper.readValue(jsonString, clazz);
}
/**
* 字符串轉(zhuǎn)換為 Map<String, Object>
*
* @param jsonString
* @return
* @throws Exception
*/
public static <T> Map<String, Object> json2map(String jsonString) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.readValue(jsonString, Map.class);
}
/**
* 字符串轉(zhuǎn)換為 Map<String, T>
*/
public static <T> Map<String, T> json2map(String jsonString, Class<T> clazz) throws Exception {
Map<String, Map<String, Object>> map = objectMapper.readValue(jsonString, new TypeReference<Map<String, T>>() {
});
Map<String, T> result = new HashMap<String, T>();
for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
}
return result;
}
/**
* 深度轉(zhuǎn)換 JSON 成 Map
*
* @param json
* @return
*/
public static Map<String, Object> json2mapDeeply(String json) throws Exception {
return json2MapRecursion(json, objectMapper);
}
/**
* 把 JSON 解析成 List,如果 List 內(nèi)部的元素存在 jsonString,繼續(xù)解析
*
* @param json
* @param mapper 解析工具
* @return
* @throws Exception
*/
private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
if (json == null) {
return null;
}
List<Object> list = mapper.readValue(json, List.class);
for (Object obj : list) {
if (obj != null && obj instanceof String) {
String str = (String) obj;
if (str.startsWith("[")) {
obj = json2ListRecursion(str, mapper);
} else if (obj.toString().startsWith("{")) {
obj = json2MapRecursion(str, mapper);
}
}
}
return list;
}
/**
* 把 JSON 解析成 Map,如果 Map 內(nèi)部的 Value 存在 jsonString,繼續(xù)解析
*
* @param json
* @param mapper
* @return
* @throws Exception
*/
private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
if (json == null) {
return null;
}
Map<String, Object> map = mapper.readValue(json, Map.class);
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object obj = entry.getValue();
if (obj != null && obj instanceof String) {
String str = ((String) obj);
if (str.startsWith("[")) {
List<?> list = json2ListRecursion(str, mapper);
map.put(entry.getKey(), list);
} else if (str.startsWith("{")) {
Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
map.put(entry.getKey(), mapRecursion);
}
}
}
return map;
}
/**
* 將 JSON 數(shù)組轉(zhuǎn)換為集合
*
* @param jsonArrayStr
* @param clazz
* @return
* @throws Exception
*/
public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
JavaType javaType = getCollectionType(ArrayList.class, clazz);
List<T> list = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
return list;
}
/**
* 獲取泛型的 Collection Type
*
* @param collectionClass 泛型的Collection
* @param elementClasses 元素類(lèi)
* @return JavaType Java類(lèi)型
* @since 1.0
*/
public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
/**
* 將 Map 轉(zhuǎn)換為 JavaBean
*
* @param map
* @param clazz
* @return
*/
public static <T> T map2pojo(Map map, Class<T> clazz) {
return objectMapper.convertValue(map, clazz);
}
/**
* 將 Map 轉(zhuǎn)換為 JSON
*
* @param map
* @return
*/
public static String mapToJson(Map map) {
try {
return objectMapper.writeValueAsString(map);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 將 JSON 對(duì)象轉(zhuǎn)換為 JavaBean
*
* @param obj
* @param clazz
* @return
*/
public static <T> T obj2pojo(Object obj, Class<T> clazz) {
return objectMapper.convertValue(obj, clazz);
}
}到此這篇關(guān)于Java中對(duì)象 和 json 互轉(zhuǎn) 四種方式 json-lib、Gson、FastJson、Jackson的文章就介紹到這了,更多相關(guān)對(duì)象和json互轉(zhuǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java中常用的json,jsonarray,map數(shù)據(jù)結(jié)構(gòu)與對(duì)象互轉(zhuǎn)詳解
- java中json和對(duì)象之間相互轉(zhuǎn)換的運(yùn)用
- JAVA中JSONObject對(duì)象和Map對(duì)象之間的相互轉(zhuǎn)換
- Java實(shí)現(xiàn)Json字符串與Object對(duì)象相互轉(zhuǎn)換的方式總結(jié)
- 詳談Java中net.sf.json包關(guān)于JSON與對(duì)象互轉(zhuǎn)的坑
- 基于JSON和java對(duì)象的互轉(zhuǎn)方法
- java對(duì)象與json對(duì)象間的相互轉(zhuǎn)換的方法
- java中實(shí)體類(lèi)和JSON對(duì)象之間相互轉(zhuǎn)化
- Java中Json字符串和Java對(duì)象的互轉(zhuǎn)
相關(guān)文章
JS求多個(gè)數(shù)組的重復(fù)數(shù)據(jù)
這篇文章主要介紹了JS求多個(gè)數(shù)組的重復(fù)數(shù)據(jù)的辦法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
win10 java(jdk安裝)環(huán)境變量配置和相關(guān)問(wèn)題
這篇文章主要介紹了win10java(jdk安裝)環(huán)境變量配置和相關(guān)問(wèn)題解決,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
IntelliJ IDEA 中使用jRebel進(jìn)行 Java 熱部署教程圖解
Rebel是一款JAVA虛擬機(jī)插件,它使得JAVA程序員能在不進(jìn)行重部署的情況下,即時(shí)看到代碼的改變對(duì)一個(gè)應(yīng)用程序帶來(lái)的影響。本文通過(guò)圖文并茂的形式給大家介紹了IntelliJ IDEA 中使用jRebel進(jìn)行 Java 熱部署教程圖解,需要的朋友參考下吧2018-04-04
spring mvc 使用kaptcha配置生成驗(yàn)證碼實(shí)例
本篇文章主要介紹了spring mvc 使用kaptcha生成驗(yàn)證碼實(shí)例,詳細(xì)的介紹了使用Kaptcha 生成驗(yàn)證碼的步驟,有興趣的可以了解一下2017-04-04
springboot整合SSE技術(shù)開(kāi)發(fā)小結(jié)
本文主要介紹了springboot整合SSE技術(shù)開(kāi)發(fā)小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11
Spring Boot使用FastJson解析JSON數(shù)據(jù)的方法
本篇文章主要介紹了Spring Boot使用FastJson解析JSON數(shù)據(jù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02

