Java解析json(三):fastjson
阿新 • • 發佈:2019-01-23
介紹
fastjson是一個Java語言編寫的JSON處理器。
- 遵循 http://json.org 標準,為其官方網站收錄的參考實現之一。
- 功能比較強大,支援JDK的各種型別,包括基本的JavaBean、Collection、Map、Date、Enum、泛型。
要求: 序列化的類符合Java bean規範。
主要API
Fastjson API入口類是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON類上的靜態方法直接完成。
反序列化
public static final Object parse(String text); // 把JSON字串轉化為JSONObject或者JSONArray
public static final JSONObject parseObject(String text); // 把JSON字串轉化為JSONObject
public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文字parse為JavaBean
public static final JSONArray parseArray(String text); // 把JSON文字parse成JSONArray
public static final <T> List<T> parseArray (String text, Class<T> clazz); //把JSON字串轉化為JavaBean集合
序列化
public static final String toJSONString(Object object); // 將JavaBean序列化為JSON文字
public static final String toJSONString(Object object, boolean prettyFormat); // 將JavaBean序列化為帶格式的JSON字串
public static final Object toJSON(Object javaObject); //將JavaBean轉換為JSONObject或者JSONArray。
測試案例
環境
- jdk1.7+
- 第三方jar包:fastjson-1.2.23.jar
常用型別
JavaBean, List<JavaBean>, List<String>, List<Map< String,Object> >
(1) JavaBean
Bean bean = JSON.parseObject(jsonString, bean.class);
(2)List<JavaBean>
List<bean> list =JSON.parseArray(jsonString, bean.class);
(3)List<String>
List<String> listString = JSON.parseArray(jsonString, String.class);
(4)List<Map<String,Object>>
List<Map<String, Object>> listMap = JSON.parseObject(jsonString, new TypeReference<List<Map<String,Object>>>(){});
JsonObject無序 JsonArray有序
@Test
public void Str2JsonObject(){
String jsonObjectStr = "{'zhangxy':'張學友','liudh':'劉德華','lim':'黎明','guofc':'郭富城'}" ;
//做5次測試
for(int i=0,j=5;i<j;i++) //多次測試,無序
{
JSONObject jsonObject = JSONObject.parseObject(jsonObjectStr) ;
for(java.util.Map.Entry<String,Object> entry:jsonObject.entrySet()){
System.out.print(entry.getKey()+"-"+entry.getValue()+"\t");
}
System.out.println();//用來換行
}
}
結果(無序):
zhangxy-張學友 guofc-郭富城 lim-黎明 liudh-劉德華
zhangxy-張學友 guofc-郭富城 lim-黎明 liudh-劉德華
zhangxy-張學友 guofc-郭富城 lim-黎明 liudh-劉德華
zhangxy-張學友 guofc-郭富城 lim-黎明 liudh-劉德華
zhangxy-張學友 guofc-郭富城 lim-黎明 liudh-劉德華
@Test
public void Str2JsonArray(){
String jsonArrayStr = "[{'zhangxy':'張學友'}, {'liudh':'劉德華'},{'lim':'黎明'},{'guofc':'郭富城'}]" ;
//做5次測試
for(int j=0;j<5;j++) //多次測試,有序
{
JSONArray jsonArray = JSONArray.parseArray(jsonArrayStr) ;
for (int k=0; k<jsonArray.size();k++){
System.out.print(jsonArray.get(k) + "\t");
}
System.out.println();//用來換行
}
}
結果(有序):
{"zhangxy":"張學友"} {"liudh":"劉德華"} {"lim":"黎明"} {"guofc":"郭富城"}
{"zhangxy":"張學友"} {"liudh":"劉德華"} {"lim":"黎明"} {"guofc":"郭富城"}
{"zhangxy":"張學友"} {"liudh":"劉德華"} {"lim":"黎明"} {"guofc":"郭富城"}
{"zhangxy":"張學友"} {"liudh":"劉德華"} {"lim":"黎明"} {"guofc":"郭富城"}
{"zhangxy":"張學友"} {"liudh":"劉德華"} {"lim":"黎明"} {"guofc":"郭富城"}
Bean和json相互轉換
簡單物件與json互相轉換
admin.java
class Admin{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
測試類
/**
* 物件陣列轉json
*/
@Test
public void JsonStr2Bean(){
Admin admin1 = new Admin();
admin1.setId(1);
admin1.setName("nowu");
Admin admin2 = new Admin();
admin2.setId(2);
admin2.setName("seeme");
Admin[] arrStr = {admin1,admin2};
String arrJsonStr = JSON.toJSONString(arrStr); //[{"id":1,"name":"admin1"},{"id":2,"name":"admin2"}]
// List<Admin> transfer2AdminList = (List<Admin>) JSON.parseObject(arrJsonStr, new TypeReference<List<Admin>>(){});
List<Admin> transfer2AdminList = (List<Admin>) JSON.parseArray(arrJsonStr, Admin.class);
for (Admin admin: transfer2AdminList) {
System.out.println(admin.getId()+":"+admin.getName());
}
}
輸出結果:
1:nowu
2:seeme
複雜物件與json互相轉換
Bean中必須符合javaBean規範,如必須有無參建構函式,getter/setter書寫規範等。
Computer.java
import java.util.Date;
public class Computer {
private Integer id;
private Date produceTime;
private String encodeNo;
public Computer(){} //必須有
public Computer(Integer id, Date produceTime, String encodeNo) {
super();
this.id = id;
this.produceTime = produceTime;
this.encodeNo = encodeNo;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getProduceTime() {
return produceTime;
}
public void setProduceTime(Date produceTime) {
this.produceTime = produceTime;
}
public String getEncodeNo() {
return encodeNo;
}
public void setEncodeNo(String encodeNo) {
this.encodeNo = encodeNo;
}
}
Seller.java
import java.util.List;
class Seller{
private int id;
private String name;
private List<Computer> list;
public Seller(){} //必須有
public Seller(int id, String name, List<Computer> list) {
super();
this.id = id;
this.name = name;
this.list = list;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Computer> getList() {
return list;
}
public void setList(List<Computer> list) {
this.list = list;
}
}
測試程式碼:
@Test
public void JsonStr2ComplexBean(){
Computer c1 = new Computer(1,new Date(), "No.1");
Computer c2 = new Computer(1,new Date(), "No.2");
Computer c3 = new Computer(1,new Date(), "No.3");
List<Computer> list = new ArrayList<Computer>();
list.add(c1);
list.add(c2);
list.add(c3);
Seller seller = new Seller(1, "seller1", list);
String sellerJsonStr = JSONObject.toJSONString(seller);
System.out.println(sellerJsonStr);
//{
// "id":1,
// "list":[{"encodeNo":"No.1","id":1,"produceTime":1487414094918},
// {"encodeNo":"No.2","id":1,"produceTime":1487414094918},
// {"encodeNo":"No.3","id":1,"produceTime":1487414094918}],
// "name":"seller1"
//}
Seller transfer2Seller = JSON.parseObject(sellerJsonStr, Seller.class);
System.out.println(transfer2Seller.getId());
for (Computer computer: transfer2Seller.getList()) {
System.out.println(computer.getId()+" : "+computer.getEncodeNo());
}
}
輸出結果:
1
1 : No.1
1 : No.2
1 : No.3
List和json相互轉換
/**
* json轉list
*/
@Test
public void JsonStr2List(){
//List -> JSON array
Admin admin1 = new Admin();
admin1.setId(1);
admin1.setName("admin1");
Admin admin2 = new Admin();
admin2.setId(2);
admin2.setName("admin2");
List<Admin> list = new ArrayList<>();
list.add(admin1);
list.add(admin2);
String listJsonStr = JSON.toJSONString(list);
System.out.println("list2json result:"+listJsonStr);
//JSON array -> List
List<Admin> list2 = JSON.parseArray(listJsonStr, Admin.class);
for (Admin admin: list2) {
System.out.println("id:"+admin.getId() +" name:"+admin.getName());
}
}
執行結果:
list2json result: [{"id":1,"name":"admin1"},{"id":2,"name":"admin2"}]
id:1 name:admin1
id:2 name:admin2
Array和json相互轉換
普通陣列與json的互相轉換:
/**
* array轉json
*/
@Test
public void Array2Json(){
String[] arrStr = {"a","b","c","d"};
String arrJsonStr = JSON.toJSONString(arrStr);
System.out.println("arr2str result:"+arrJsonStr);
JSONArray jsonArray = JSON.parseArray(arrJsonStr);
for (Object object : jsonArray) {
System.out.println("iterator from JsonArray: "+object);
}
System.out.println("JsonArray:"+jsonArray);
}
執行結果:
arr2str result:["a","b","c","d"]
iterator from JsonArray: a
iterator from JsonArray: b
iterator from JsonArray: c
iterator from JsonArray: d
JsonArray:["a","b","c","d"]
物件陣列與json的互相轉換:
/**
* 物件陣列轉json
*/
@Test
public void ObjectArray2Json(){
Admin admin1 = new Admin();
admin1.setId(1);
admin1.setName("admin1");
Admin admin2 = new Admin();
admin2.setId(2);
admin2.setName("admin2");
Admin[] arrStr = {admin1,admin2};
String arrJsonStr = JSON.toJSONString(arrStr,true);
System.out.println("objectarr2str result:"+arrJsonStr);
JSONArray jsonArray = JSON.parseArray(arrJsonStr);
for (Object object : jsonArray) {
System.out.println("iterator from JsonArray: "+object);
}
System.out.println("JsonArray:"+jsonArray);
}
Map和json相互轉換
/**
* json轉map
*/
@Test
public void JsonStr2Map(){
//Map -> JSON
Admin admin1 = new Admin();
admin1.setId(1);
admin1.setName("admin1");
Admin admin2 = new Admin();
admin2.setId(2);
admin2.setName("admin2");
Map<String, Admin> map = new HashMap<String, Admin>();
map.put("admin1", admin1);
map.put("admin2", admin2);
String mapJsonStr = JSON.toJSONString(map);
System.out.println("map2json result:"+mapJsonStr);
//JSON -> Map
Map<String, Admin> mapFromJson = (Map<String, Admin>) JSON.parse(mapJsonStr);
for (String key: mapFromJson.keySet()) {
System.out.println("key:"+ key+" value:"+mapFromJson.get(key));
}
}
執行結果:
map2json result:{"admin2":{"id":2,"name":"admin2"},"admin1":{"id":1,"name":"admin1"}}
key:admin2 value:{"id":2,"name":"admin2"}
key:admin1 value:{"id":1,"name":"admin1"}
重複引用
/**
* 重複引用
*/
@Test
public void RepeatedRef() {
List<Admin> list = new ArrayList<>();
Admin admin = new Admin();
admin.setId(1);
admin.setName("haha");
list.add(admin);
list.add(admin);
String s = JSON.toJSONString(list);
System.out.println(s);
}
執行結果:
[{"id":1,"name":"haha"},{"$ref":"$[0]"}]
迴圈引用
User.java
class User{
private int id;
private String name;
private Group group;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
Group.java
import java.util.ArrayList;
import java.util.List;
class Group{
private int id;
private String name;
private List<User> list = new ArrayList<User>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
}
/**
* 迴圈引用
*/
@Test
public void RecyleRef(){
Group group = new Group();
group.setId(1);
group.setName("group");
User user1 = new User();
user1.setId(2);
user1.setName("user1");
user1.setGroup(group);
User user2 = new User();
user2.setId(3);
user2.setName("user2");
user2.setGroup(group);
group.getList().add(user1);
group.getList().add(user2);
JSON.toJSONString(group, SerializerFeature.DisableCircularReferenceDetect); //java.lang.StackOverflowError
}
迴圈引用,假如關閉引用檢查的話,執行會報StackOverflowError。不要關閉自定義的引用檢查
可以解決這個問題,但有時候想重複引用時並不想fastjson檢查我們的引用,所以這種辦法有時不靠譜,另一種為設定過濾欄位,自定義序列化欄位。
過濾和自定義序列化
SerializeFilter是通過程式設計擴充套件的方式定製序列化。fastjson支援6種SerializeFilter,用於不同場景的定製序列化。
- PropertyPreFilter :根據PropertyName判斷是否序列化
- PropertyFilter:根據PropertyName和PropertyValue來判斷是否序列化
- NameFilter 修改Key,如果需要修改Key,process返回值則可
- ValueFilter 修改Value
- BeforeFilter :序列化時在最前面新增內容
- AfterFilter :序列化時在最後面新增內容
@Test
public void RecyleRef(){
Group group = new Group();
group.setId(1);
group.setName("group");
User user1 = new User();
user1.setId(2);
user1.setName("user1");
user1.setGroup(group);
User user2 = new User();
user2.setId(3);
user2.setName("user2");
user2.setGroup(group);
group.getList().add(user1);
group.getList().add(user2);
SimplePropertyPreFilter filter = new SimplePropertyPreFilter(User.class,"id","name");
String result = JSON.toJSONString(group,filter);
System.out.println(result);
}
執行結果:
{"id":1,"list":[{"id":2,"name":"user1"},{"id":3,"name":"user2"}],"name":"group"}
@Test
public void Define1(){
Group group = new Group();
group.setId(1);
group.setName("group");
User user1 = new User();
user1.setId(2);
user1.setName("user1");
user1.setGroup(group);
User user2 = new User();
user2.setId(3);
user2.setName("user2");
user2.setGroup(group);
group.getList().add(user1);
group.getList().add(user2);
//自定義序列化過濾器
ValueFilter valueFilter = new ValueFilter() {
@Override
public Object process(Object o, String propertyName, Object propertyValue) {
if(propertyName.equals("group")){
return new String("i am group"); //返回修改後的屬性值物件
}
return propertyValue;
}
};
String result = JSON.toJSONString(group,valueFilter);
System.out.println(result);
}
執行結果:
{"id":1,"list":[{"group":"i am group","id":2,"name":"user1"},{"group":"i am group","id":3,"name":"user2"}],"name":"group"}
日期格式化
註解@JSONField
@JSONField (format=”yyyy-MM-dd HH:mm:ss”)
public Date date;
通過SerializeConfig
@Test
public void formatDateTest(){
China china = new China();
china.setId(1);
china.setName("中國");
china.setCreateTime(new Date());
List<Province> provinces = new ArrayList<>();
Province hei = new Province();
hei.setName("黑龍江");
City heiCity = new City();
heiCity.setCity(new String[] { "哈爾濱", "大慶" });
hei.setCitys(heiCity);
provinces.add(hei);
Province guang = new Province();
guang.setName("廣東");
City guangCity = new City();
guangCity.setCity(new String[] { "廣州", "深圳", "珠海" });
guang.setCitys(guangCity);
provinces.add(guang);
Province tai = new Province();
tai.setName("臺灣");
City taiCity = new City();
taiCity.setCity(new String[] { "臺北", "高雄 " });
tai.setCitys(taiCity);
provinces.add(tai);
china.setProvinces(provinces);
SerializeConfig serializeConfig = new SerializeConfig();
String dateFormat = "yyyy-MM-dd HH:mm:ss";
serializeConfig.put(Date.class, new SimpleDateFormatSerializer(dateFormat));
String result=JSON.toJSONString(china,serializeConfig);
System.out.println(result);
}
SerializerFeature.WriteDateUseDateFormat
String result=JSON.toJSONString(china,SerializerFeature.WriteDateUseDateFormat);
JSON.toJSONStringWithDateFormat
String result = JSON.toJSONStringWithDateFormat(china, "yyyy-MM-dd HH:mm:ss.SSS");
fastjson工具類
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.JSONLibDataFormatSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
/**
* fastjson工具類
*/
public class FastJsonUtils {
private static final SerializeConfig config;
static {
config = new SerializeConfig();
config.put(java.util.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib相容的日期輸出格式
config.put(java.sql.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib相容的日期輸出格式
}
private static final SerializerFeature[] features = {
SerializerFeature.WriteMapNullValue, // 輸出空置欄位
SerializerFeature.WriteNullListAsEmpty, // list欄位如果為null,輸出為[],而不是null
SerializerFeature.WriteNullNumberAsZero, // 數值欄位如果為null,輸出為0,而不是null
SerializerFeature.WriteNullBooleanAsFalse, // Boolean欄位如果為null,輸出為false,而不是null
SerializerFeature.WriteNullStringAsEmpty, // 字元型別欄位如果為null,輸出為"",而不是null
};
public static String toJSONString(Object object) {
return JSON.toJSONString(object, config, features);
}
public static String toJSONNoFeatures(Object object) {
return JSON.toJSONString(object, config);
}
public static Object toBean(String text) {
return JSON.parse(text);
}
public static <T> T toBean(String text, Class<T> clazz) {
return JSON.parseObject(text, clazz);
}
// 轉換為陣列
public static <T> Object[] toArray(String text) {
return toArray(text, null);
}
// 轉換為陣列
public static <T> Object[] toArray(String text, Class<T> clazz) {
return JSON.parseArray(text, clazz).toArray();
}
// 轉換為List
public static <T> List<T> toList(String text, Class<T> clazz) {
return JSON.parseArray(text, clazz);
}
/**
* 將javabean轉化為序列化的json字串
* @param keyvalue
* @return
*/
public static <T> Object beanToJson(T t) {
String textJson = JSON.toJSONString(t);
Object objectJson = JSON.parse(textJson);
return objectJson;
}
/**
* 將string轉化為序列化的json字串
* @param keyvalue
* @return
*/
public static Object textToJson(String text) {
Object objectJson = JSON.parse(text);
return objectJson;
}
/**
* json字串轉化為map
* @param s
* @return
*/
public static Map stringToCollect(String s) {
Map m = JSONObject.parseObject(s);
return m;
}
/**
* 將map轉化為string
* @param m
* @return
*/
public static String collectToString(Map m) {
String s = JSONObject.toJSONString(m);
return s;
}
}