Jackson
庫,是基於java語言的開源json格式解析工具。Jackson兩大分支codehaus
、fasterxml
。參考:Jackson兩大分支codehaus、fasterxml的區別Jackson
從2.0開始改用新的包名fasterxml
,1.x版本的包名是codehaus。若是是新項目,建議直接用2x,即fasterxml jackson
。
整個庫包含3個jar包:html
<!-- Jackson依賴庫 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <!--2.8.8--> <version>${dependency.version.jackson}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${dependency.version.jackson}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${dependency.version.jackson}</version> </dependency>
說明:java
jackson-core
——核心包(必須),提供基於「流模式」解析的API。jackson-databind
——數據綁定包(可選),提供基於「對象綁定」和「樹模型」相關API。jackson-annotations
——註解包(可選),提供註解功能。其餘:數據庫
在時候用mybatis時,還有如下包,用於映射LocalDateTime與數據庫中的time:json
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-typehandlers-jsr310</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency>
@JsonSerialize
該註解部分源碼以下:mybatis
package com.fasterxml.jackson.databind.annotation; @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotation public @interface JsonSerialize { Class<? extends JsonSerializer> using() default None.class; Class<? extends JsonSerializer> contentUsing() default None.class; Class<? extends JsonSerializer> keyUsing() default None.class; ...
說明:app
RUNTIME
時,可反射獲取;using
字段,傳入格式爲繼承了JsonSerializer
的類的字節碼Class<? extends JsonSerializer>
。JsonSerializer
類中,有一個抽象方法須要實現:ide
public abstract class JsonSerializer<T> implements JsonFormatVisitable { ... public abstract void serialize(T var1, JsonGenerator var2, SerializerProvider var3) throws IOException, JsonProcessingException; ... }
其中:工具
T
爲待轉換的數據對象;JsonGenerator
主要用於生成目標json
,有一系列的寫
方法,如:writeStartObject()
、writeString()
等。(見下參考)
JsonGenerator
參考:測試
JsonGenerator
write
後的數據,即爲轉化後的數據。示例見下。.net
說明:
只有在調用序列化方法後,註解纔會生效。僅僅註解某個元素後,打印結果,該註解並不會生效。
默認序列化,僅使用com.fasterxml.jackson.databind.ObjectMapper
下的writeValueAsString(yourEntity)
,便可序列化。如:
package jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonSerialize; public class CustomDoubleTest { private Double price; private String name; // getter and setter and toString... public static void main(String[] args) { CustomDoubleTest t = new CustomDoubleTest(); t.setPrice(3.14159); try { String serialized = new ObjectMapper().writeValueAsString(t); System.out.println(serialized); } catch (JsonProcessingException e) { e.printStackTrace(); } } }
該bean
的默認序列化結果格式:
{"price":"3.14159","name":null}
根據標題2.1
中所述,使用註解@JsonSerialize
時,傳入using
參數的類,需實現JsonSerializer
。
/** * 將Double類型轉換成保留兩位小數的格式的字符串 */ public class CustomDoubleSerialize extends JsonSerializer<Double> { @Override public void serialize(Double aDouble, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { /** jsonGenerator寫後的數據即爲轉換後的數據 */ jsonGenerator.writeString(new DecimalFormat("##.00").format(aDouble)); //jsonGenerator.writeString("test"); } }
public class CustomDoubleTest { /** * 該註解能夠放在字段、getter或setter上 */ @JsonSerialize(using = CustomDoubleSerialize.class) private Double price; private String name; // 相似上述... public static void main(String[] args) { CustomDoubleTest t = new CustomDoubleTest(); t.setPrice(3.14159); /** 1.直接打印被註解的字段,即便有註解也不起做用 */ System.out.println("不調用序列化方法即便有註解也不會生效:"+t.getPrice()); /** 2.直接打印對象,按toString打印。即便有註解也不起做用 */ System.out.println(t); try { /** 該方法調用序列化方法,會以json格式展現 * 1.若是沒有註解,仍然按默認的json格式展現 * 2.若是有註解(打開註釋),按註解格式展現 * */ String serialized = new ObjectMapper().writeValueAsString(t); // 3.只有在調用序列化方法時,纔會觸發該註解。 System.out.println("調用序列化方法後,註解才生效:"+serialized); } catch (JsonProcessingException e) { e.printStackTrace(); } }
結果:
不調用序列化方法即便有註解也不會生效:3.14159 CustomDoubleTest{price=3.14159, name='null'} 調用序列化方法後,註解才生效:{"price":"3.14","name":null}
默認的序列化,能夠將複雜的對象按默認格式序列化。如:
public class CustomDoubleTest1 { private int id; private String name; private List<CustomDoubleTest> list; private Map<Integer,String> pair; private Set<String> set; private Boolean flag; ... }
使用默認序列化後:
public static void main(String[] args) { CustomDoubleTest1 t = new CustomDoubleTest1(); // 給對象t賦值 t.setId(1); t.setName("hobe"); Map pair = new HashMap(); pair.put(1,"wang"); pair.put(2,"hong"); pair.put(3,"bing"); t.setPair(pair); List<CustomDoubleTest> list = new ArrayList<>(); list.add(new CustomDoubleTest()); t.setList(list); Set<String> set = new HashSet(); set.add("whbing.cn"); t.setSet(set); t.setFlag(true); try { /** * com.fasterxml.jackson.databind.ObjectMapper * 僅一個方法便可【將對象解析成json字符串】 */ String serialized = new ObjectMapper().writeValueAsString(t); // 只有在調用序列化方法時,纔會觸發該註解。 System.out.println(serialized); } catch (JsonProcessingException e) { e.printStackTrace(); } }
將會默認序列化爲如下格式:
{ "id": 1, "name": "hobe", "list": [{ "price": null, "name": null }], "pair": { "1": "wang", "2": "hong", "3": "bing" }, "set": ["whbing.cn"], "flag": true }
即對象
和Map
將會以{}
包裹,List
和Set
將會以[]包裹。
高級自定義序列化
參考: jackson中自定義處理序列化和反序列化
public class CustomBeanSerialize extends JsonSerializer<CustomDoubleTest1> { @Override public void serialize(CustomDoubleTest1 entity, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { jsonGenerator.writeStartObject(); jsonGenerator.writeNumberField("id",entity.getId()); jsonGenerator.writeStringField("mapValue",entity.getList().get(0).getName()); jsonGenerator.writeEndObject(); } }
@JsonSerialize(using = CustomBeanSerialize.class) public class CustomDoubleTest1 { ...
String serialized = new ObjectMapper().writeValueAsString(t);
顯示結果以下:
{"id":1,"mapValue":null}