實體對象轉成字段排列有序的JSON字符串
一、背景說明
有一些場景,需要將實體對象中的字段有序地轉成JSON字符串。
使用fastjson轉換后,默認是按照字段首字母升序排序的,並不會按照實體中字段定義的順序進行排序。
效果如下:
1、創建英雄類
package com.miracle.luna.sorted; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; /** * @author Miracle Luna * @date 2021/6/30 */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Hero { private String name; // 姓名
private String gender; // 性別
private String career; // 職業
}
其中,類上添加了 lombok 的注解,可以減少在類中寫getter、setter、無參構造、全參構造 和 toString 等方法。
可以使代碼看着簡潔很多。
2、實體轉換成JSON字符串
package com.miracle.luna.sorted; import com.alibaba.fastjson.JSONObject; import java.util.ArrayList; import java.util.List; /** * @author Miracle Luna * @date 2021/6/30 */
public class EntityToJSONString { public static void main(String[] args) { List<Hero> heroList = new ArrayList<>(); heroList.add(new Hero("李白", "男", "刺客")); heroList.add(new Hero("典韋", "男", "戰士")); heroList.add(new Hero("甄姬", "女", "法師")); heroList.add(new Hero("伽羅", "女", "射手")); heroList.add(new Hero("白起", "男", "坦克")); heroList.add(new Hero("庄周", "男", "輔助")); heroList.forEach(hero -> System.out.println(JSONObject.toJSONString(hero))); } }
執行結果如下:
{"career":"刺客","gender":"男","name":"李白"} {"career":"戰士","gender":"男","name":"典韋"} {"career":"法師","gender":"女","name":"甄姬"} {"career":"射手","gender":"女","name":"伽羅"} {"career":"坦克","gender":"男","name":"白起"} {"career":"輔助","gender":"男","name":"庄周"}
可以直觀地看到,轉換后的JSON字符串是按照字段的首字母進行了排序(career --> gender --> name),
並沒有按照實體中字段的定義順序進行排序(name--> gender --> career)。
二、實現方案
在定義實體的每個字段上,添加fastjson的 注解 @JSONField(ordinal = X)
其中,X 表示個人希望該字段在轉為JSON字段串時所在的位置。
package com.miracle.luna.sorted; import com.alibaba.fastjson.annotation.JSONField; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; /** * @author Miracle Luna * @date 2021/6/30 */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Hero { @JSONField(ordinal = 1) private String name; // 姓名
@JSONField(ordinal = 2) private String gender; // 性別
@JSONField(ordinal = 3) private String career; // 職業
}
再次執行測試類,運行結果如下:
{"name":"李白","gender":"男","career":"刺客"} {"name":"典韋","gender":"男","career":"戰士"} {"name":"甄姬","gender":"女","career":"法師"} {"name":"伽羅","gender":"女","career":"射手"} {"name":"白起","gender":"男","career":"坦克"} {"name":"庄周","gender":"男","career":"輔助"}
可以看到和我們預期的效果一致,是按照實體中字段的設置順序進行排序的(name--> gender --> career)。