Jackson 是一个能够将java对象序列化为JSON字符串,也能够将JSON字符串反序列化为java对象的框架。

本文的所有内容都可以从 Java JSON Jackson Introduction 中找到,这里记录下来供自己以后参考,如果时间充足,建议阅读原文。

这是另一篇介绍自定义(反)序列化的文章 http://www.baeldung.com/jackson-custom-serialization

无论是序列化还是反序列化,Jackson都提供了三种方式:

1. JSON <--> Java Object

2. JSON <--> JsonNode Tree(类似于XML的DOM树)

3. JSON <--> Json Stream (这是一个低层次的api,很强大,但是很繁琐)

Jackson提供了很多有用的注解来定制序列化,但是我们完全不用它的注解也可以完成绝大多数的工作。下面就从上面三种方式来一一介绍。

JSON <--> Java Object

下面的Person类是一个普通的java POJO。它含有基本类型(包括String、Date)和一些集合类型,以及一个自定义的Address类型。

注意: 默认情况下,Jackson会处理所有public的属性和拥有getter方法的属性(反序列化需要setter)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class Person {private String name;private int age;public Date birth;private Address address;private List<String> friends = new ArrayList<>();public Map<String, String> info = new HashMap<>();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 List<String> getFriends() {return friends;}public void setFriends(List<String> friends) {this.friends = friends;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}//注意这个默认构造器,如果没有默认的构造器,应该有一个@JsonCreator修饰的构造器public Person(){}public Person(String name, int age, Address address, Date birth, String... friends){this.name = name;this.age = age;this.address = address;this.birth = birth;this.friends.addAll(Arrays.asList(friends));}@Overridepublic String toString() {StringBuffer sb = new StringBuffer();sb.append("name: " + this.name + "\n");sb.append("age: " + this.age + "\n");sb.append("address: " + this.address + "\n");sb.append("birth: " + this.birth + "\n");this.friends.forEach(x -> sb.append("friend:"+ x + "\n"));return sb.toString();}
}
public class Address {public String homeAddress;public String workAddress;//跟Person一样,我们也必须提供一个无参的默认构造器public Address(){}public Address(String homeAddress, String workAddress) {this.homeAddress = homeAddress;this.workAddress = workAddress;}@Overridepublic String toString() {return "home:" + this.homeAddress + "  " + "work:" + this.workAddress;}
}

下面我们使用Jackson来(反)序列化 这个Person对象。

序列化:

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;public class SerializeTest {public static void main(String[] args) throws ParseException, JsonGenerationException, JsonMappingException, IOException {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");Date birth = format.parse("2010-10-10");Address address = new Address("New York", "Tokyo");Person person = new Person("zhangsan", 11, address, birth, "weiying", "caifang");person.info.put("height", "175cm");person.info.put("weight", "80kg");//使用ObjectMapper来序列化和反序列化ObjectMapper mapper = new ObjectMapper();//配置序列化的输出缩进mapper.configure(SerializationFeature.INDENT_OUTPUT, true);//如果没有DateFormat,ObjectMapper将会把Date类型序列化为毫秒数
        mapper.setDateFormat(format);//按照map的key的自然排序来产生序列化结果mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);//序列化的过程就这一行代码,当然也可以选择输出到文件或其他流中mapper.writeValue(new File("person.json"), person);}
}

反序列化:

import java.io.File;
import java.io.IOException;import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;public class DeserializeTest {public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {//反序列化同样从ObjectMapper开始ObjectMapper mapper = new ObjectMapper();//配置在反序列化过程中如果json字符串中存在无法匹配的属性不会失败mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//上面的configure(xxx,false) 等同于disable(xxx),例如下面这行和上面作用是一样的。
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);//反序列化的过程也仅仅只有一行代码,同样可以从文件或其他流等输入中进行反序列化Person person = mapper.readValue(new File("person.json"), Person.class);System.out.println(person);}
}

在上面的例子中我们看到了Jackson最基本的(反)序列化过程,下面我们介绍一些用来定制(反)序列化的注解:

1.@JsonProperty - 在默认情况下,Jackson会处理所有public的属性和拥有getter(序列化)和setter(反序列化)的属性。但是我们可以使用 @JsonProperty来手动指定我们希望jackson处理的属性。于此同时,我们可以改变java对象映射到json中的属性名称(默认是相同的)。@JsonProperty相当于JAXB中的@XmlElement注解。

import java.io.File;
import java.io.IOException;import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;/*** 这个Dog类型没有任何public的属性和getter方法,但是我们使用@JsonProperty可以手动指定希望(反)序列化的属性,并能指定希望映射到json中的属性名称*/
public class Dog {@JsonProperty("dog_name")private String name = "dahuang";private int age;@JsonProperty("dog_age")private int tellYourAge(){return this.age;}@JsonProperty("dog_age")private void giveMeAge(int age){this.age = age;}@Overridepublic String toString() {return "dog(name: " + name + ";age: " + age + ")";}public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {ObjectMapper mapper = new ObjectMapper();//Jackson序列化空对象默认为失败
        mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);//配置ObjectMapper有两种方式,除了上面那种,下面这行代码是等价的。mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//配置序列化格式
        mapper.enable(SerializationFeature.INDENT_OUTPUT);//上面这行代码同样等价于下面这行mapper.configure(SerializationFeature.INDENT_OUTPUT, true);mapper.writeValue(new File("dog.json"), new Dog());Dog dog = mapper.readValue(new File("dog.json"), Dog.class);System.out.println(dog);}
}

2.@JsonCreator - 在上面Person的例子中,我们除了定义了一个有参数的构造器外,还必须定义一个无参的默认构造器,这是因为在反序列化的过程中,Jackson不知道该向那个有参数的构造器中传递什么参数。 我们可以在构造器上使用 @JsonCreator,并在参数列表中使用@JsonProperty,这样在反序列化时Jackson就知道该如何使用这个构造器了,这个时候我们也就没必要定义那个无参的默认构造器了。

注意@JsonCreator仅仅在反序列化的过程中有用。

import java.io.File;
import java.io.IOException;import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;public class Dog {public String name;public int age;@Overridepublic String toString() {return this.name + ":" + this.age;}//在反序列化的过程中,Jackson会将json串中的name属性传递给dog_name参数, 把json串中的age属性传递给dog_age参数。
    @JsonCreatorpublic Dog(@JsonProperty("name") String dog_name, @JsonProperty("age") int dog_age){this.name = dog_name;this.age = dog_age;}public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {ObjectMapper mapper = new ObjectMapper();mapper.writeValue(new File("dog.json"), new Dog("dahuang", 11));Dog dog = mapper.readValue(new File("dog.json"), Dog.class);System.out.println(dog);}
}

3.@JsonAnyGetter and @JsonAnySetter - 设想这样一种场景:除了java对象中明确指定的属性(包括使用@JsonProperty修饰指定的)外,我们希望能够随机的增加一些其他属性,让这些随机的属性也可以映射到json中去。这个时候我们就可以将这些不确定的属性放到一个map中去,并使用@JsonAnyGetter和@JsonAnySetter来修饰处理这个map的方法,然后Jackson就可以处理这些不确定的属性了。这两个属性相当于JAXB中的@XmlAnyElement和@XMLAnyAttribute。

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;public class Dog {private Map<String, String> any = new HashMap<>();@JsonAnyGetterpublic Map<String, String> getAny(){return this.any;}@JsonAnySetterpublic void setAny(String key, String value){this.any.put(key, value);}public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {Dog dog = new Dog();//suck a big dog!!!dog.setAny("height", "175cm");dog.setAny("weight", "80kg");ObjectMapper mapper = new ObjectMapper();mapper.writerWithDefaultPrettyPrinter().writeValue(new File("dog.json"), dog);Dog dog2 = mapper.readValue(new File("dog.json"), Dog.class);dog2.getAny().forEach((x, y) -> System.out.println(x + "-->" + y));}
}

4.@JsonIgnoreProperties and @JsonIgnore - 如果我们不希望Jackson处理java对象中public的属性或者拥有getter方法的属性,我们就可以使用这两个属性来忽略它们,相当于JAXB中@XmlTransient。

import java.io.IOException;import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;@JsonIgnoreProperties({"name", "age"})
public class Dog {public String name = "dahuang";public int age = 11;@JsonIgnorepublic String home = "CHN";public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {ObjectMapper mapper = new ObjectMapper();mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);//Dog的所有属性都已经被忽略了,所以此时应该序列化为一个空json串mapper.writeValue(System.out, new Dog());}}

除了使用@JsonIgnoreProperties and @JsonIgnore来忽略特定属性外,还可以像下面这样忽略空的属性:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;public class Dog {public String name = "";public List<String> info = new ArrayList<>();public List<String> info2 = null;public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {ObjectMapper mapper = new ObjectMapper();mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);//下面这行代码会忽略所有null或者空的属性,所以Dog此时依旧会被序列化为空JSON串
        mapper.setSerializationInclusion(Include.NON_EMPTY);mapper.writeValue(System.out, new Dog());}
}

5.在序列化的过程中保存类型信息

下面定义了一个父类Animal和它的两个子类Dog和Cat,Person类有一个Animal类型的属性。

Animal:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;public class Animal {public String name;public int age;@JsonCreatorpublic Animal(@JsonProperty("name") String name, @JsonProperty("age") int age){this.name = name;this.age = age;}
}

Dog:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;public class Dog extends Animal{public String size;@JsonCreatorpublic Dog(@JsonProperty("name") String name, @JsonProperty("age") int age, @JsonProperty("size") String size){super(name, age);this.size = size;}
}

Cat:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;public class Cat extends Animal{public String color;@JsonCreatorpublic Cat(@JsonProperty("name") String name, @JsonProperty("age") int age, @JsonProperty("color") String color){super(name, age);this.color = color;}
}

Person:

public class Person {public Animal animal;
}

我们现在为Person的animal属性设置为Dog对象,然后序列化Person对象,之后再用得到的json串反序列化。

import java.io.File;
import java.io.IOException;import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;public class Test {public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {Person person = new Person();person.animal = new Dog("dahuang", 11, "big");ObjectMapper mapper = new ObjectMapper();mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);mapper.writeValue(new File("person.json"), person);Person p2 = mapper.readValue(new File("person.json"), Person.class);//在序列化的时候我们为Person对象animal属性赋予的是一个Dog对象,但是反序列化后得到的animal属性仅仅是一个animal对象。//实际上,如果Animal是一个抽象类型的话,此时就会报错了。
        System.out.println(p2.animal.getClass().getName());}
}

在上面的例子序列化的结果是:

{"animal" : {"name" : "dahuang","age" : 11,"size" : "big"}
}

在上面的结果中我们看到Jackson并没有将animal属性的具体类型信息保存下来,这样在反序列化的时候,Jackson就无法知道之前序列化时的真正类型,这就是上面反序列化后得到的是一个Animal而不是Dog的原因。

我们修改Animal如下:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "@class")
@JsonSubTypes({ @Type(value = Dog.class, name = "lion"), @Type(value = Cat.class, name = "elephant") })
public class Animal {public String name;public int age;@JsonCreatorpublic Animal(@JsonProperty("name") String name, @JsonProperty("age") int age){this.name = name;this.age = age;}
}

然后再次执行上面那段序列化和反序列化的代码,便可以得到Person的animal属性是一个Dog对象了。 序列化的json为:

{"animal" : {"@class" : "com.massclouds.info.Dog","name" : "dahuang","age" : 11,"size" : "big"}
}

我们看到上面的json结果中多了一个@class的属性,它就代表了animal属性的类型信息。

当我们直接序列化一个Animal的list或者以Animal为value的map时,上面的设置依旧无法将类型信息保存到json串中,下面我们演示如何直接(反)序列化包含Animal的list和map(注意此时Animal上的注解依旧要有)。

序列化:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;public class SerializeList {public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {List<Animal> animal_list = new ArrayList<>();animal_list.add(new Dog("dahuang", 11, "big"));animal_list.add(new Cat("miaomiao", 11, "grey"));Map<String, Animal> animal_map = new HashMap<>();animal_map.put("dog", new Dog("dahuagn", 11, "big"));animal_map.put("cat", new Cat("miaomiao", 11, "white"));ObjectMapper mapper = new ObjectMapper();mapper.enable(SerializationFeature.INDENT_OUTPUT);mapper.writerFor(new TypeReference<List<Animal>>(){}).writeValue(new File("list.json"), animal_list);mapper.writerFor(new TypeReference<Map<String, Animal>>(){}).writeValue(new File("map.json"), animal_map);}
}

反序列化:

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;public class SerializeList {public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {ObjectMapper mapper = new ObjectMapper();List<Animal> animal_list = mapper.readValue(new File("list.json"), new TypeReference<List<Animal>>(){});animal_list.forEach(animal -> System.out.println(animal.getClass().getName()));Map<String, Animal> animal_map = mapper.readValue(new File("map.json"), new TypeReference<Map<String, Animal>>(){});animal_map.forEach((key, value) -> System.out.println(key + " --> " + value.getClass().getName()));}
}

上面需要注意的地方就是 由于Class对象中是不能携带泛型信息的,所以需要使用TypeReference。

6. Mix-in

当我们使用的是第三方类库中的Java类型时,我们无法直接在类型上使用注解,此时我们可以使用Jackson提供的Mix-in功能。

我们有一个Dog类如下:

public class Dog {public String name;private int age;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Dog(String name, int age){this.name = name;this.age = age;}
}

我们需要定义一个抽象类,如果我们希望在Dog类的什么地方使用注解,我们就在这个抽象类中定义一个相同的声明(属性或者方法),然后使用注解,例如我们希望在Dog中的getAge方法上使用@JsonProperty注解,那么我们就在这个抽象类中定义一个名称为getAge的抽象方法,然后再在这个抽象方法上使用@JsonProperty。下面是这个抽象类的实现:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;public abstract class DogMixin{@JsonProperty("dog_name")public String name;@JsonProperty("dog_age")public abstract int getAge();@JsonProperty("dog_age")public abstract void setAge(int age);@JsonCreatorpublic DogMixin(@JsonProperty("dog_name") String name,@JsonProperty("dog_age") int age){//这里可以啥都没有。。。
    }
}

然后在序列化的时候,像下面这样使用,就可以跟直接在Dog类中使用注解产生一样的效果了。

import java.io.File;
import java.io.IOException;import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;public class Test {public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {ObjectMapper mapper = new ObjectMapper();//注册我们使用的Mixin抽象类mapper.addMixIn(Dog.class, DogMixin.class);Dog dog = new Dog("dahuang", 11);mapper.writerWithDefaultPrettyPrinter().writeValue(new File("dog.json"), dog);Dog dog2 = mapper.readValue(new File("dog.json"), Dog.class);System.out.println(dog2.getAge() + " : " + dog2.name);}
}

JSON <--> JsonNode Tree

就如同XML的DOM树一样,我们同样可以通过一颗json节点树来构建json,当然也可以将一个json字符串反序列化为一颗节点树。

Tree2JSON

import java.io.FileOutputStream;
import java.io.IOException;import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;public class Tree2JSON {public static void main(String[] args) throws IOException {JsonFactory jsonFactory = new JsonFactory();JsonGenerator generator = jsonFactory.createGenerator(new FileOutputStream("tree.json"));ObjectMapper mapper = new ObjectMapper();JsonNodeFactory factory = new JsonNodeFactory(false);//生成一个根节点ObjectNode person = factory.objectNode();//普通属性直接添加即可person.put("name", "zhangsan");person.put("age",  11);//可以生成一个对象节点,然后把这个节点加入为根节点的子节点ObjectNode address = factory.objectNode();address.put("homeAddress", "New York");address.put("workAddress", "Tokyo");person.set("address", address);//同样可以生成一个Array节点, 然后把这个Array节点加入为根节点的子节点ArrayNode friends = factory.arrayNode();ObjectNode friend1 = factory.objectNode();friend1.put("name", "weiying");ObjectNode friend2 = factory.objectNode();friend2.put("name", "caifang");friends.add(friend1).add(friend2);person.set("friends", friends);mapper.writeTree(generator, person);}
}

产生的json字符串为(我不知道在这种情况下序列化这个JSON,要是你知道请告诉我):

{"name":"zhangsan","age":11,"address":{"homeAddress":"New York","workAddress":"Tokyo"},"friends":[{"name":"weiying"},{"name":"caifang"}]}

下面将这个JSON串反序列化为一颗树,并遍历这颗树:

import java.io.File;
import java.io.IOException;
import java.util.Iterator;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;public class JSON2Tree {public static void main(String[] args) throws JsonProcessingException, IOException {ObjectMapper mapper = new ObjectMapper();// ObjectMapper读取json,返回根节点JsonNode root = mapper.readTree(new File("tree.json"));review(root);}// 递归遍历整棵树private static void review(JsonNode root) {if (root.getNodeType().equals(JsonNodeType.OBJECT)) {Iterator<String> fieldNames = root.fieldNames();while (fieldNames.hasNext()) {String fieldName = fieldNames.next();JsonNode node = root.get(fieldName);System.out.println(fieldName);review(node);}} else if (root.getNodeType().equals(JsonNodeType.ARRAY)) {ArrayNode array = (ArrayNode) root;Iterator<JsonNode> iter = array.iterator();iter.forEachRemaining(x -> review(x));} else {System.out.println(root);}}
}

JSON <--> Json Stream

Jackson提供了一种低层次的操作json的api,简单的说,就是Jackson读取json串后,会依次将json中的每个标志都产生相应的token,例如"{"表示对象的开始,那么Jackson 就产生一个表示对象开始的token。它很强大,但是很繁琐,不推荐使用。

import java.io.File;
import java.io.IOException;import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;public class StramParser {public static void main(String[] args) throws JsonParseException, IOException {JsonFactory factory = new JsonFactory();JsonParser parser = factory.createParser(new File("person.json"));while(!parser.isClosed()){//这里仅仅简单的打印出token的类型和值(如果有的话)JsonToken token = parser.nextToken();System.out.println(token);System.out.println(parser.getText());}}
}
import java.io.IOException;import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;public class StreamGenerator {public static void main(String[] args) throws IOException {JsonFactory factory = new JsonFactory();JsonGenerator generator = factory.createGenerator(System.out);// start writing with {        generator.writeStartObject();generator.writeFieldName("name");generator.writeString("zhangsan");generator.writeFieldName("address");// start an array
        generator.writeStartArray();generator.writeStartObject();generator.writeStringField("homeAddress", "New York");generator.writeEndObject();generator.writeStartObject();generator.writeStringField("workAddress", "Tokyo");generator.writeEndObject();generator.writeEndArray();generator.writeEndObject();generator.close();}
}

Jackson详细介绍相关推荐

  1. Jackson使用详细介绍

    Jackson使用详细介绍 一 . Jackson 介绍 二. Jackson Maven 依赖 三. ObjectMapper 对象映射器 四. Jackson JSON 基本操作 1. Jacks ...

  2. Canal Mysql binlog 同步至 ElasticSearch 详细介绍

    文章目录 数据同步ElasticSearch 单表基本配置 适配器映射文件详细介绍(单表.多表映射介绍) 单表映射索引示例sql 单表映射索引示例sql带函数或运算操作 多表映射(一对一, 多对一)索 ...

  3. springboo日志t详细介绍

    springboot详细介绍 序: 诞生简介 优缺点 springboot日志介绍 1.默认行为 2.自定义日志 3.不适用xml,直接使用yml或者properties配置 yml 配置: prop ...

  4. FRIENDS演员详细介绍

    FRIENDS演员详细介绍 Jennifer Aniston Pitt (Rachel Karen Green) Jen有着希腊血统,在孩提时代曾在希腊生活过一年,因为她父亲的演艺事业全家迁到了纽约. ...

  5. 小熊听书项目的详细介绍

    目录 一.项目概述 二.项目需求 2.1功能需求 2.2 其他需求 2.3系统功能流程图 2.4总体设计 三.开发环境 四.准备工作 五.介绍文件的存放规则 六.各部分功能的详细介绍 1.建立数据库与 ...

  6. HTML页面加载和解析流程详细介绍

    浏览器加载和渲染html的顺序.如何加快HTML页面加载速度.HTML页面加载和解析流程等等,在本文将为大家详细介绍下,感兴趣的朋友不要错过 浏览器加载和渲染html的顺序 1. IE下载的顺序是从上 ...

  7. mysql为什么要压测_mysql集群压测的详细介绍

    本篇文章给大家带来的内容是关于mysql集群压测的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. mysql压测 mysql自带就有一个叫mysqlslap的压力测试工具,通 ...

  8. php比较运算符案列,PHP实例:PHP比较运算符的详细介绍

    <PHP实例:PHP比较运算符的详细介绍>要点: 本文介绍了PHP实例:PHP比较运算符的详细介绍,希望对您有用.如果有疑问,可以联系我们. 比拟运算符种类 PHP实战如同它们名称所暗示的 ...

  9. Tempdb数据库详细介绍

    Tempdb数据库详细介绍 一.Tempdb简介 tempdb是SQLServer的系统数据库一直都是SQLServer的重要组成部分,用来存储临时对象.可以简单理解tempdb是SQLServer的 ...

最新文章

  1. Spark的安装和使用
  2. 10个你必须知道的jQueryMobile代码片段
  3. bresenham算法画圆mfc实现_kd-tree理论以及在PCL 中的代码的实现
  4. gif动态图片生成器,多张图片组合后生成动图...
  5. 浅谈WebView利用localStore websql和IndexDB 来存储数据
  6. WPS有空白页老删不掉,delete和退格都删不了
  7. 市场车载音响麦克风摆放以及降噪解决方案
  8. 8051 系列单片机内部结构
  9. win10不让桌面上显示宽带连接服务器,Win10宽带连接不见了
  10. 加权有限状态转录机(Weighted Finite-State Transducer/WFST)
  11. 【寻找最佳小程序】11期:车来了——时时公交就在你身边,到站准确率可控制在90%以上...
  12. 1.0.16-Python练习题-求一张纸对折多少次能达到珠峰高度
  13. input-group两侧添加额外元素
  14. 用python爬取百科糗事的小项目
  15. 点云IO篇之stl文件读写
  16. 货币金额大写格式(银行需要)
  17. java 工作业绩_个人年度工作总结报告java
  18. 初夏,开源魔改一个带击杀音效的电蚊拍!
  19. Mac 显示隐藏文件 如.m2
  20. Flutter桌面开发 - windows插件开发

热门文章

  1. 草草读罢《苏菲的世界》
  2. 大一计算机上机试题2017,2017大一计算机基础试题及答案
  3. 计算机专业有哪些科研项目,计算机专业文献检索的课题有哪些
  4. hadoop配置文件详解系列(一)-core-site.xml篇
  5. 智慧城市发展新机遇,逐步从理论构想进化到实践
  6. GoAccess 分析nginx日志
  7. 2022.10.4 英语背诵
  8. 基于matlab的扩频通信系统建模与仿真,基于Simulink的基带数字通信系统的仿真实现...
  9. 使用VB 6.0使用XML和文本文件进行数据管理:第一部分
  10. 记录一下对接腾讯云IM的部分接口(群聊、单聊)