Java之Jackson框架

在Jackson框架中,提供了三種方式用來處理JSON數據:java

流式API

在該方式下,使用JsonParser讀取JSON數據,使用JsonGenerator寫JSON數據。這種方式性能最佳(最低開銷、最快速度讀/寫,其餘兩種方式基於該方式實現)node

public static void write2JsonByStreamApi() throws Exception {
    JsonFactory jf = new JsonFactory();
    JsonGenerator jg = jf.createGenerator(new File("D:/user.json"),
            JsonEncoding.UTF8);
    jg.writeStartObject();
        
    jg.writeObjectFieldStart("users");
    jg.writeStringField("name", "jackson");
    jg.writeNumberField("age", 13);
    jg.writeEndObject();
        
    jg.writeEndObject();
    jg.flush();
    jg.close();
}

 

樹模型

在該模式下,將JSON數據以樹的方式存儲在內存中,使用ObjectMapper讀取JSON數據生成樹,樹是JsonNode節點的集合json

數據綁定

在該模式下,能夠方便的將JSON和POJO相互轉化,數據的綁定有兩種變體:app

  • 簡單數據綁定

簡單數據綁定是指Map、List、String、Numbers、Boolean、以及null之間的相互轉化,其轉化對應以下:框架

JSON Type Java Type
Object LinkedHashMap<String,Object>
Array ArrayList<Object>
String String
Number(整數)

Integer、Long、BigIntegeride

Number(小數) Double
True|False Boolean
Null Null

 

 

  • 完整數據綁定

完整數據綁定是指任何Java Bean類型上述簡單數據綁定進行轉換函數

/*********************************************/
/**父母信息類*/
public class Parent {
    private String fathername = "";
    private String mothername = ""; 
    public Parent() {
        /**JSON串轉爲Java對象時調用無慘構造函數*/
    }
    public Parent(String fname,String mname) {
        this.fathername = fname;
        this.mothername = mname;
    }
    public String getFathername() {
        return fathername;
    }
    public void setFathername(String fathername) {
        this.fathername = fathername;
    }
    public String getMothername() {
        return mothername;
    }
    public void setMothername(String mothername) {
        this.mothername = mothername;
    }
}
/**教師信息類*/
public class Teacher {
    private String name = "";
    private int age = 0;
    public Teacher() {
       /**JSON串轉爲Java對象時調用無慘構造函數*/
    }
    public Teacher(String name,int age) {
        this.name = name;
        this.age = age;
    }
    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 class Student {
    private String name = "";
    private String sex = "";
    private int age = 0;
    private Parent parent = null;
    private Teacher[] teachers = null;
    public Student() {
        /**JSON串轉爲Java對象時調用無慘構造函數*/
    }
    public Student(String name,String sex,int age){
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Parent getParent() {
        return parent;
    }
    public void setParent(Parent parent) {
        this.parent = parent;
    }
    public Teacher[] getTeachers() {
        return teachers;
    }
    public void setTeachers(Teacher[] teachers) {
        this.teachers = teachers;
    }
}
/*********************************************/
public class JSonUtil {
    private static ObjectMapper mapper = null; 
    static {
        mapper = new ObjectMapper();
    }
    public static void write2Json(Object obj) throws IOException {
        mapper.writeValue(System.out, obj);
    }
    public static Object json2Object(String json,Class<? extends Object> clazz) throws Exception {
        return mapper.readValue(json, clazz);
    }
    public static void main(String []args) throws Exception {
        /**Java對象轉化爲JSON串*/
        Parent parent = new Parent("張大龍","張園園");
        Teacher teacher_1 = new Teacher("李大成",46);
        Teacher teacher_2 = new Teacher("王大虎",43);
        Student student = new Student("張明","男",22);
        student.setParent(parent);
        student.setTeachers(new Teacher[]{teacher_1,teacher_2});
        JSonUtil.write2Json(student);
        /**JSON串轉換爲Java對象*/
        String json = "{\"name\":\"張明\",\"sex\":\"男\",\"age\":22," +"\"parent\":{\"fathername\":\"張大龍\",\"mothername\":\"張園園\"}," + "\"teachers\":[{\"name\":\"李大成\",\"age\":46}," + "{\"name\":\"王大虎\",\"age\":43}]}";
        Student student = (Student) JSonUtil.json2Object(json, Student.class);
        System.out.println(student.getParent().getFathername());
    }
}
/*************************輸出結果*****************************/
{"name":"張明","sex":"男","age":22,"parent":{"fathername":"張大龍","mothername":"張園園"},"teachers":[{"name":"李大成","age":46},{"name":"王大虎","age":43}]}

  

 

在上面的示例中,須要注意的是:性能

  1. 將JSON串轉爲Java對象時,須要Java對象提供無參的構造函數,而且要求Java對象具備Java Bean性質,也就是說要有setter/getter方法
  2. 將Java對象轉爲JSON字符串時,JSON串Object的key名稱取自Java對象的屬性名稱,若是想改變JSON串Object的key名稱須要重寫本身的序列化器,在解析時須要重寫反序列化器,而且在序列化器中指定JSON串順序
/**序列化器*/
public class StudentSerializer extends JsonSerializer<Student> {
    @Override
    public void serialize(Student value, JsonGenerator js, SerializerProvider provider) throws IOException,
            JsonProcessingException {
        // TODO Auto-generated method stub
        js.writeStartObject();
        
        js.writeObjectField("學生姓名", value.getName());
        js.writeObjectField("性別", value.getSex());
        js.writeObjectField("年齡", value.getAge());
        js.writeFieldName("父母信息");
        
        js.writeStartObject();
        js.writeObjectField("父親姓名", value.getParent().getFathername());
        js.writeObjectField("母親姓名", value.getParent().getMothername());
        js.writeEndObject();
        
        js.writeArrayFieldStart("教師信息");
        Teacher [] teachers = value.getTeachers();
        for(Teacher teacher : teachers) {
            js.writeStartObject();
            js.writeObjectField("教師姓名", teacher.getName());
            js.writeObjectField("教師年齡", teacher.getAge());
            js.writeEndObject();
        }
        js.writeEndArray();
        
        js.writeEndObject();
    }
}
/**反序列化器*/
public class StudentDeserializer extends JsonDeserializer<Student> {
    @Override
    public Student deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {
        // TODO Auto-generated method stub
        JsonNode node = parser.getCodec().readTree(parser);
        String name = node.get("學生姓名").asText();
        String sex = node.get("性別").asText();
        int age = node.get("年齡").asInt();
        JsonNode pNode = node.get("父母信息");
        String fathername = pNode.get("父親姓名").asText();
        String mothername = pNode.get("母親姓名").asText();
        Parent parent = new Parent();
        parent.setFathername(fathername);
        parent.setMothername(mothername);
        JsonNode tNodes = node.get("教師信息");
        ArrayList<Teacher> list = new ArrayList<Teacher>();
        for(JsonNode tNode : tNodes) {
            String teachername = tNode.get("教師姓名").asText();
            int teacherage = tNode.get("教師年齡").asInt();
            Teacher teacher = new Teacher();
            teacher.setName(teachername);
            teacher.setAge(teacherage);
            list.add(teacher);
        }
        Student student = new Student();
        student.setName(name);
        student.setAge(age);
        student.setSex(sex);
        student.setParent(parent);
        student.setTeachers((Teacher[]) list.toArray(new Teacher[]{}));
        return student;
    }
}
/**************************************************************/
public class JSonUtil {
    private static ObjectMapper mapper = null; 
    static {
        mapper = new ObjectMapper();
        /**註冊序列化器與反序列化器*/
        StudentSerializer ser = new StudentSerializer();
        StudentDeserializer deser = new StudentDeserializer();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Student.class, ser);
        module.addDeserializer(Student.class, deser);
        mapper.registerModule(module);
    }
    public static void write2Json(Object obj) throws IOException {
        mapper.writeValue(System.out, obj);
    }
    public static Object json2Object(String json,Class<? extends Object> clazz) throws Exception {
        return mapper.readValue(json, clazz);
    }
    public static void main(String []args) throws Exception {
        Parent parent = new Parent("張大龍","張園園");
        Teacher teacher_1 = new Teacher("李大成",46);
        Teacher teacher_2 = new Teacher("王大虎",43);
        Student student = new Student("張明","男",22);
        student.setParent(parent);
        student.setTeachers(new Teacher[]{teacher_1,teacher_2});
        JSonUtil.write2Json(student);
        String json = "{\"學生姓名\":\"張明\",\"性別\":\"男\",\"年齡\":22," +  "\"父母信息\":{\"父親姓名\":\"張大龍\",\"母親姓名\":\"張園園\"}," + "\"教師信息\":[{\"教師姓名\":\"李大成\",\"教師年齡\":46}," + "{\"教師姓名\":\"王大虎\",\"教師年齡\":43}]}";
        Student stu = (Student) JSonUtil.json2Object(json, Student.class);
        System.out.println(stu.getParent().getFathername());
    }
}

  

在上面的序列化示例中,能夠看出須要將自定義的序列化器與反序列化器註冊到ObjectMapper中,在Jackson2.x框架中,提供了註解方式this

/*************序列化對象添加註解***************/
@JsonSerialize(using = StudentSerializer.class) 
@JsonDeserialize(using = StudentDeserializer.class)
public class Student {
    private String name = "";
    private String sex = "";
    private int age = 0;
    private Parent parent = null;
    private Teacher[] teachers = null;
    public Student() {
        
    }
    public Student(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Parent getParent() {
        return parent;
    }
    public void setParent(Parent parent) {
        this.parent = parent;
    }
    public Teacher[] getTeachers() {
        return teachers;
    }
    public void setTeachers(Teacher[] teachers) {
        this.teachers = teachers;
    }
}
/***********************************************/
public class JSonUtil {
    private static ObjectMapper mapper = null; 
    static {
        mapper = new ObjectMapper();
    }
    public static void write2Json(Object obj) throws IOException {
        mapper.writeValue(System.out, obj);
    }
    public static Object json2Object(String json,Class<? extends Object> clazz) throws Exception {
        return mapper.readValue(json, clazz);
    }
    public static void main(String []args) throws Exception {
        Parent parent = new Parent("張大龍", "張園園");
        Teacher teacher_1 = new Teacher("李大成", 46);
        Teacher teacher_2 = new Teacher("王大虎", 43);
        Student student = new Student("張明", "男", 22);
        student.setParent(parent);
        student.setTeachers(new Teacher[] { teacher_1, teacher_2 });
        JSonUtil.write2Json(student);
        String json = "{\"學生姓名\":\"張明\",\"性別\":\"男\",\"年齡\":22,"
                + "\"父母信息\":{\"父親姓名\":\"張大龍\",\"母親姓名\":\"張園園\"},"
                + "\"教師信息\":[{\"教師姓名\":\"李大成\",\"教師年齡\":46},"
                + "{\"教師姓名\":\"王大虎\",\"教師年齡\":43}]}";
        Student stu = (Student) JSonUtil.json2Object(json, Student.class);
        System.out.println(stu.getParent().getFathername());

    }
}

 

  • 泛型的數據綁定

除綁定到POJO和簡單類型外,還有一個額外的變型:綁定到泛型容器,因爲所謂的類型擦除【Java採用向後兼容的方式實現泛型】,須要進行特殊處理,這時須要藉助TypeReference類spa

/*********************************************/
public class PersonMsg {
    private String name;
    private String sex;
    public PersonMsg() {
        
    }
    public PersonMsg(String name,String sex) {
        this.name = name;
        this.sex = sex;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
}
/*********************************************/
public class JSonUtil {
    private static ObjectMapper mapper = null; 
    static {
        mapper = new ObjectMapper();
    }
    public static void write2Json(Object obj) throws IOException {
        mapper.writeValue(System.out, obj);
    }
    public static Object json2Object(String json,TypeReference<Map<String,PersonMsg>> typeReference) throws Exception {
        return mapper.readValue(json, typeReference);
    }
    public static void main(String []args) throws Exception {
        PersonMsg p0 = new PersonMsg("liming", "man");
        PersonMsg p1 = new PersonMsg("lixiang", "woman");
        Map<String, PersonMsg> map = new HashMap<String, PersonMsg>();
        map.put("liming", p0);
        map.put("lixiang", p1);
        JSonUtil.write2Json(map);
        String json = "{\"liming\":{\"name\":\"liming\",\"sex\":\"man\"}," +
                "\"lixiang\":{\"name\":\"lixiang\",\"sex\":\"woman\"}}";
        Map<String,PersonMsg> pmap = (Map<String, PersonMsg>) JSonUtil.json2Object(json, new TypeReference<Map<String,PersonMsg>>(){});
    }
}
相關文章
相關標籤/搜索