在Jackson框架中,提供了三种方式用来处理JSON数据:
流式API
在该方式下,使用JsonParser读取JSON数据,使用JsonGenerator写JSON数据。这种方式性能最佳(最低开销、最快速度读/写,其他两种方式基于该方式实现)
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和POJO相互转化,数据的绑定有两种变体:
- 简单数据绑定
简单数据绑定是指Map、List、String、Numbers、Boolean、以及null之间的相互转化,其转化对应如下:
JSON Type | Java Type |
Object | LinkedHashMap<String,Object> |
Array | ArrayList<Object> |
String | String |
Number(整数) |
Integer、Long、BigInteger |
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}]}
在上面的示例中,需要注意的是:
- 将JSON串转为Java对象时,需要Java对象提供无参的构造函数,并且要求Java对象具有Java Bean性质,也就是说要有setter/getter方法
- 将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框架中,提供了注解方式
/*************序列化对象添加注解***************/ @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类
/*********************************************/ 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>>(){}); } }