解決json字符串序列化后的順序問題
1、應(yīng)用場景:
如果項目中用到j(luò)son字符串轉(zhuǎn)為jsonObject的需求,并且,需要保證字符串的順序轉(zhuǎn)之前和轉(zhuǎn)成jsonObject之后輸出的結(jié)果完全一致??赡苡悬c繞口,下面舉一個應(yīng)用場景的例子。
在做項目的過程中,需要寫Junit單元測試,有一個方法如下:
@Test @SuppressWarnings("unchecked") public void facilitySoftwareQueryByPageExample() throws Exception { facilitySoftwareRepository.deleteAll(); FacilitySoftwareConfig facilitySoftware = createFacilitySoftware(); facilitySoftwareRepository.save(facilitySoftware); String userId = "1"; int pageNumber = 1; int pageSize = 5; String facilities = objectMapper.writeValueAsString(facilitySoftware); LinkedHashMap<String, Object> jsonMap = JSON.parseObject(facilities,LinkedHashMap.class, Feature.OrderedField); JSONArray jsonArray = new JSONArray(); JSONObject jsonObject = new JSONObject(true); jsonObject.putAll(jsonMap); jsonArray.add(jsonObject); this.mockMvc .perform(get("/v1/facilitysoftware/userid/" + userId + "/page/" + pageNumber + "/pagesize/" + pageSize + "")) .andExpect(status().isOk()).andExpect(jsonPath("content",is(jsonArray))) .andExpect(jsonPath("totalPages", is(1))) .andExpect(jsonPath("totalElements", is(1))) .andExpect(jsonPath("last", is(true))) .andExpect(jsonPath("number", is(0))) .andExpect(jsonPath("size", is(5))) .andExpect(jsonPath("numberOfElements", is(1))) .andExpect(jsonPath("first", is(true))) .andDo(document("facilitySoftware-query-example")); }
例子就在這里:
.andExpect(status().isOk()).andExpect(jsonPath("content",is(jsonArray)))
大家應(yīng)該都能讀懂,這行代碼意思就是你用Api獲取到的json字符串和你定義的字符串是否一致,一致則該條件測試通過。
這里的比較不僅僅要求所有的key和value都相同,而且需要保證兩個json串的順序完全相同,才可以完成該條件的測試。
查了資料解決途徑過程如下:首先我們使用的是阿里的fastJson,需要引入fastJson的依賴,具體百度maven倉庫,注意這里盡量使用穩(wěn)定版本的較高版本。如 1.2.*
在解決問題過程中,遇到如下解決方案
1、在初始化json對象的時候加上參數(shù)true,這里不完全符合我們的需求,加上true之后,是讓json串按照key的hashcode排序。
可以自定義升序或者降序,因為解決不了該場景的問題。這里不贅述,自行百度。
JSONObject jsonObject = new JSONObject(true);
2、解決問題,代碼如下,第一個參數(shù)是需要轉(zhuǎn)換的json字符串。
LinkedHashMap<String, Object> jsonMap = JSON.parseObject(facilities,LinkedHashMap.class, Feature.OrderedField);
JSONArray jsonArray = new JSONArray(); JSONObject jsonObject = new JSONObject(true); jsonObject.putAll(jsonMap); jsonArray.add(jsonObject);
補充:JSON 序列化key排序問題和序列化大小寫問題
1. JSON 序列化key排序問題(fastjson)
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.PropertyFilter; import com.alibaba.fastjson.serializer.SerializerFeature; //創(chuàng)建學(xué)生對象 Student student = new Student(); student.setName("小明"); student.setSex(1); student.setAge(18); //序列化 json key按字典排序 System.out.println(JSONObject.toJSONString(student ,SerializerFeature.MapSortField)); //過濾不要的key age System.out.println(JSONObject.toJSONString(student , new PropertyFilter() { public boolean apply(Object source, String name, Object value) { if ("age".equals(name)) { return false; } return true; } }, SerializerFeature.MapSortField));
2. JSON 序列化大小寫問題(fastjson)
//學(xué)生類 import com.alibaba.fastjson.annotation.JSONField; public class Student { private String name; private Integer sex; private Integer age; @JSONField(name = "Name") //用于序列化成json,key Name public String getName() { return name; } @JSONField(name = "Name") 用于json(Name)反序列化成學(xué)生對象 public void setName(String name) { this.name = name; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
3. jackson 序列化大小寫問題
@ResponseBody和@RequestBody中的序列化和反序列化就是用的jackson
//學(xué)生類 import com.fasterxml.jackson.annotation.JsonProperty; public class Student { @JsonProperty("Name") private String name; private Integer sex; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } //自己測試下 import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; @Test public void test() throws Exception{ Student student = new Student(); student.setName("小明"); ObjectMapper MAPPER = new ObjectMapper(); //jackson序列化 String json = MAPPER.writeValueAsString(student); System.out.println(json); //jackson反序列化 Student student2 = MAPPER.readValue(json, Student.class); System.out.println(student2.getName()); }
4. jackson 序列化null值的問題
fastjson序列化默認(rèn)會去掉值為null的鍵值對
//在學(xué)生類上加上這個 方式一:(已經(jīng)過時的方法) import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) 方式二: import com.fasterxml.jackson.annotation.JsonInclude; @JsonInclude(JsonInclude.Include.NON_NULL)
5. jackson 反序列化忽略多余的json字段
import com.fasterxml.jackson.databind.DeserializationFeature; MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
6. jackson 序列化忽略多余的json字段
方式一: @JsonIgnoreProperties:該注解將在類曾級別上使用以忽略json屬性。在下面的栗子中,我們將從albums的dataset中忽略“tag”屬性; @JsonIgnoreProperties({ "tags" }) 方式二: @JsonIgnore:該注釋將在屬性級別上使用以忽略特定屬性;get方法上 @JsonIgnore
7. jackson 常用注解
@JsonAlias("Name") 反序列化時生效 private String name; @JsonProperty("Name") 反序列化和序列化都時生效 private String name;
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
jxl 導(dǎo)出數(shù)據(jù)到excel的實例講解
下面小編就為大家分享一篇jxl 導(dǎo)出數(shù)據(jù)到excel的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12Windows10系統(tǒng)下JDK1.8的下載安裝及環(huán)境變量配置的教程
這篇文章主要介紹了Windows10系統(tǒng)下JDK1.8的下載安裝及環(huán)境變量配置的教程,本文圖文并茂給大家介紹的非常詳細(xì),對大家的工作或?qū)W習(xí)具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03淺談Java中ArrayList的擴(kuò)容機(jī)制
本文主要介紹了淺談Java中ArrayList的擴(kuò)容機(jī)制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06spring-cloud-gateway動態(tài)路由的實現(xiàn)方法
這篇文章主要介紹了spring-cloud-gateway動態(tài)路由的實現(xiàn)方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01