轉自:https://www.ibm.com/developerworks/cn/java/jackson-advanced-application/index.htmlhtml
不一樣類型的日期類型,Jackson 的處理方式也不一樣。java
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.9.1</version> </dependency>
對於 Jackson 2.5 如下版本,須要添加代碼 objectMapper.registerModule(new JSR310Module ())node
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> <version>2.9.1</version> </dependency>
Jackson 對泛型反序列化也提供很好的支持。sql
CollectionType javaType = mapper.getTypeFactory() .constructCollectionType(List.class, Person.class); List<Person> personList = mapper.readValue(jsonInString, javaType); List<Person> personList = mapper.readValue(jsonInString, new TypeReference<List<Person>>(){});
//第二參數是 map 的 key 的類型,第三參數是 map 的 value 的類型 MapType javaType = mapper.getTypeFactory().constructMapType(HashMap.class,String.class, Person.class); Map<String, Person> personMap = mapper.readValue(jsonInString, javaType); Map<String, Person> personMap = mapper.readValue(jsonInString, new TypeReference<Map<String, Person>>() {});
是 java 對象的全部的屬性都被序列化和反序列化,換言之,不是全部屬性均可視化,默認的屬性可視化的規則以下:json
若想更改默認的屬性可視化的規則,須要調用 ObjectMapper 的方法 setVisibility。app
下面的示例使修飾符爲 protected 的屬性 name 也能夠序列化和反序列化。框架
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); public class Person { public int age; protected String name; } PropertyAccessor 支持的類型有 ALL,CREATOR,FIELD,GETTER,IS_GETTER,NONE,SETTER Visibility 支持的類型有 A NY,DEFAULT,NON_PRIVATE,NONE,PROTECTED_AND_PUBLIC,PUBLIC_ONLY
在將 Java 對象序列化爲 json 時 ,有些屬性須要過濾掉,不顯示在 json 中 , Jackson 有多種實現方法。ide
@JsonIgnore public int getAge() @JsonIgnoreProperties(value = { "age","birth_date" }) public class Person
addMixIn 方法簽名以下:spa
public ObjectMapper addMixIn(Class<?> target, Class<?> mixinSource);code
addMixIn 方法的做用是用 mixinSource 接口或類的註解會重寫 target 或 target 的子類型的註解。 用ixIn 設置
Person peixIn 的 @JsonIgnoreProperties("name")所重寫,最終忽略的屬性爲 name,最終生成的 json 以下:
{"birthDate":"2017/09/13","age":40}
首先須要設置@JsonFilter 類或接口,其次設置 addMixIn,將@JsonFilter 做用於 java 對象上,最後調用 SimpleBeanPropertyFilter 的 serializeAllExcept 方法或重寫 S impleBeanPropertyFilter 的 serializeAsField 方法來過濾相關屬性。示例以下:
//設置 Filter 類或接口 @JsonFilter("myFilter") public interface MyFilter {} //設置 addMixIn mapper.addMixIn(Person.class, MyFilter.class); //調用 SimpleBeanPropertyFilter 的 serializeAllExcept 方法 SimpleBeanPropertyFilter newFilter = SimpleBeanPropertyFilter.serializeAllExcept("age"); //或重寫 SimpleBeanPropertyFilter 的 serializeAsField 方法 SimpleBeanPropertyFilter newFilter = new SimpleBeanPropertyFilter() { @Override public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception { if (!writer.getName().equals("age")) { writer.serializeAsField(pojo, jgen, provider); } } }; //設置 FilterProvider FilterProvider filterProvider = new SimpleFilterProvider() .addFilter("myFilter", newFilter); mapper.setFilterProvider(filterProvider).writeValueAsString(person);
當 Jackson 默認序列化和反序列化的類不能知足實際須要,能夠自定義新的序列化和反序列化的類。
public class CustomSerializer extends StdSerializer<Person> { @Override public void serialize(Person person, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeStartObject(); jgen.writeNumberField("age", person.getAge()); jgen.writeStringField("name", person.getName()); jgen.writeEndObject(); } }
JsonGenerator 有多種 write 方法以支持生成複雜的類型的 json,好比 writeArray,writeTree 等 。若想單首創建 JsonGenerator,能夠經過 JsonFactory() 的 createGenerator。
public class CustomDeserializer extends StdDeserializer<Person> { @Override public Person deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); Person person = new Person(); int age = (Integer) ((IntNode) node.get("age")).numberValue(); String name = node.get("name").asText(); person.setAge(age); person.setName(name); return person; } }
JsonParser 提供不少方法來讀取 json 信息, 如 isClosed(), nextToken(), getValueAsString()等。若想單首創建 JsonParser,能夠經過 JsonFactory() 的 createParser。
SimpleModule module = new SimpleModule("myModule"); module.addSerializer(new CustomSerializer(Person.class)); module.addDeserializer(Person.class, new CustomDeserializer()); mapper.registerModule(module); 也可經過註解方式加在 java 對象的屬性,方法或類上面來調用它們, @JsonSerialize(using = CustomSerializer.class) @JsonDeserialize(using = CustomDeserializer.class) public class Person
Jackson 也提供了樹模型(tree model)來生成和解析 json。若想修改或訪問 json 部分屬性,樹模型是不錯的選擇。樹模型由 JsonNode 節點組成。程序中經常使用 ObjectNode,ObjectNode 繼承於 JsonNode,示例以下:
ObjectMapper mapper = new ObjectMapper(); //構建 ObjectNode ObjectNode personNode = mapper.createObjectNode(); //添加/更改屬性 personNode.put("name","Tom"); personNode.put("age",40); ObjectNode addressNode = mapper.createObjectNode(); addressNode.put("zip","000000"); addressNode.put("street","Road NanJing"); //設置子節點 personNode.set("address",addressNode); //經過 path 查找節點 JsonNode searchNode = personNode.path("street "); //刪除屬性 ((ObjectNode) personNode).remove("address"); //讀取 json JsonNode rootNode = mapper.readTree(personNode.toString()); //JsonNode 轉換成 java 對象 Person person = mapper.treeToValue(personNode, Person.class); //java 對象轉換成 JsonNode JsonNode node = mapper.valueToTree(person);
本文首先經過與其餘 Java 的 json 的框架比較,介紹了 Jackson 的優勢,而且描述了 Jackson 的 核心模塊的組成,以及每一個部分的做用。而後, 本文經過示例,講解 Jackson 的基本用法,介紹了 ObjectMapper 的 write 和 read 方法,ObjectMapper 的配置信息設定,以及 jackson-annotations 包下注釋的運用。最後,本文詳細的介紹了 Jackson 的高階用法,這也是本文的重點。這些高階用法包括不一樣類型的日期格式處理(普通日期的類型,jdk 8 的日期類型,joda 的日期類型),List 和 Map 等泛型的反序列化,屬性的可視化管理,Jackson 的 三種屬性過濾方式,自定義序列化和反序列化的實現以及樹模型的使用。經過本文的系統地講解,相信讀者對 Jackson 會有更深入而全面的掌握。