1. 程式人生 > >Android-json解析(二):Jackson的使用

Android-json解析(二):Jackson的使用

使用Jackson,主要是使用writeValueAsString和readValue這兩個方法。此外,Jackson的writeValue和readValue有很多種引數型別,適用於多中場合。

1、匯入依賴

compile 'com.fasterxml.jackson.core:jackson-databind:2.9.0.pr3'
compile 'com.fasterxml.jackson.core:jackson-core:2.9.0.pr3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.9.0.pr3'

2、新增packagingOptions

因為jackson-core和jackson-databind有重複的檔案,重複載入會報錯。

android{

    ...
      packagingOptions {
            exclude 'META-INF/NOTICE' // will not include NOTICE file
            exclude 'META-INF/LICENSE' // will not include LICENSE file
        }
}

3、工具類:

package com.example.administrator.gsondemo;

import
com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by Administrator on 2017/5/10. */ public class JacksonUtil { private final static ObjectMapper objectMapper = new
ObjectMapper(); private JacksonUtil() { } public static ObjectMapper getInstance() { return objectMapper; } /** * javaBean,list,array convert to json string */ public static String obj2json(Object obj) throws Exception { return objectMapper.writeValueAsString(obj); } /** * json string convert to javaBean */ public static <T> T json2pojo(String jsonStr, Class<T> clazz) throws Exception { return objectMapper.readValue(jsonStr, clazz); } /** * json string convert to map */ public static <T> Map<String, Object> json2map(String jsonStr) throws Exception { return objectMapper.readValue(jsonStr, Map.class); } /** * json string convert to map with javaBean */ public static <T> Map<String, T> json2map(String jsonStr, Class<T> clazz) throws Exception { Map<String, Map<String, Object>> map = objectMapper.readValue(jsonStr, 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; } /** * json array string convert to list with javaBean */ public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception { List<Map<String, Object>> list = objectMapper.readValue(jsonArrayStr, new TypeReference<List<T>>() { }); List<T> result = new ArrayList<T>(); for (Map<String, Object> map : list) { result.add(map2pojo(map, clazz)); } return result; } /** * map convert to javaBean */ public static <T> T map2pojo(Map map, Class<T> clazz) { return objectMapper.convertValue(map, clazz); } }

4、測試

Person 類:

package com.example.administrator.gsondemo;

/**
 * Created by Administrator on 2017/5/9.
 */

public class Person {

    private String name;
    private int age;
    private Birthday birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Birthday getBirthday() {
        return birthday;
    }

    public void setBirthday(Birthday birthday) {
        this.birthday = birthday;
    }

    public Person() {
    }

    public Person(String name, int age, Birthday birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '}';
    }
}

Birthday 類:

package com.example.administrator.gsondemo;

/**
 * Created by Administrator on 2017/5/9.
 */
public class Birthday {
    private int year;
    private int month;
    private int day;

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public Birthday() {
    }

    public Birthday(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    @Override
    public String toString() {
        return "Birthday{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
}

MainActivity 類:

package com.example.administrator.gsondemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        objectsToJson_Jackson();
        objectToJson_Jackson();
    }

    /*------------------------------------Jackson----------------------------------*/


    /**
     * 單一物件的json生成與解析
     */
    public void objectToJson_Jackson() {

        Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));

        String jsonString = null;
        try {
            jsonString = JacksonUtil.obj2json(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(TAG, "---------jackson單一物件生成字串--------");
        Log.e(TAG, jsonString);
        Log.e(TAG, jsonString instanceof String ? "型別===String" : "型別不為String");


        Person person = null;
        try {
            person = JacksonUtil.json2pojo(jsonString, Person.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(TAG, "---------jackson單一字串解析成物件--------");
        Log.e(TAG, person.toString());
        Log.e(TAG, "物件的名字::::" + person.getName());
    }

    /**
     * 集合物件的json生成與解析
     */
    public void objectsToJson_Jackson() {
        Person person1 = new Person("zhaokaiqiang1", 21, new Birthday(1991, 1, 19));
        Person person2 = new Person("zhaokaiqiang2", 22, new Birthday(1992, 2, 29));
        Person person3 = new Person("zhaokaiqiang3", 23, new Birthday(1993, 3, 39));
        ArrayList<Person> arrayList = new ArrayList<Person>();
        arrayList.add(person1);
        arrayList.add(person2);
        arrayList.add(person3);

        String jsonString = null;
        try {
            jsonString = JacksonUtil.obj2json(arrayList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(TAG, "---------jackson集合物件生成字串--------");
        Log.e(TAG, jsonString);
        Log.e(TAG, jsonString instanceof String ? "型別===String" : "型別不為String");


        List<Person> persons = null;
        try {
            persons = JacksonUtil.json2list(jsonString, Person.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(TAG, "---------jackson集合字串解析成物件--------");
        Log.e(TAG, persons.toString());
        Log.e(TAG, "物件的名字::::" + persons.get(0).getName());


    }

}

5、問題及解答:

5.1 執行後報以下錯誤,請參照上面第二條:新增packagingOptions

Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/LICENSE
    File1: C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.9.0.pr3\dede10be4aaaa6893561372dc5196644268997b7\jackson-annotations-2.9.0.pr3.jar
    File2: C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.9.0.pr3\f9c6d5cfde33c589596d1f43200ec052a2c7c9c0\jackson-core-2.9.0.pr3.jar
    File3: C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.9.0.pr3\41a8d484e0fe00102724d03090503ad212ee3c20\jackson-databind-2.9.0.pr3.jar

5.2 Gson執行報錯

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to...

異常原因:
作為方法傳入引數,Java編譯過程會將泛型物件型別擦除。

解決方法:
1、直接copy方法內程式碼直接使用,而不通過方法傳入
2、不使用

public static <T> List<T> getObjectList(String jsonString,Class<T> cls){  
        List<T> list = new ArrayList<T>();  
        try {  
            Gson gson = new Gson();  
            list = gson.fromJson(jsonString, new TypeToken<List<T>>(){}.getType());  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return list;  
    }  

而使用以下:

public static <T> List<T> getObjectList(String jsonString,Class<T> cls){  
        List<T> list = new ArrayList<T>();  
        try {  
            Gson gson = new Gson();  
            JsonArray arry = new JsonParser().parse(jsonString).getAsJsonArray();  
            for (JsonElement jsonElement : arry) {  
                list.add(gson.fromJson(jsonElement, cls));  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return list;  
    }  

參考: