原文地址
1 概述
在本文中,我們將深入探討Jackson註解。
我們將看到如何使用Jackson現有的註解,如何創建自定義註解以及如何禁用它們。
2 Jackson序列化註解
2.1 @JsonAnyGetter
@JsonAnyGetter註解提供了將Map字段轉換爲標準屬性的靈活性。這是一個簡單的示例– ExtendableBean實體具有name屬性和一組以K/V對形式的可擴展屬性:
public class ExtendableBean {
public String name;
private Map<String, String> properties;
public ExtendableBean() {
properties = new HashMap<String, String>();
}
public ExtendableBean(final String name) {
this.name = name;
properties = new HashMap<String, String>();
}
@JsonAnySetter
public void add(final String key, final String value) {
properties.put(key, value);
}
@JsonAnyGetter
public Map<String, String> getProperties() {
return properties;
}
}
序列化此實體的實例時,我們將Map中的所有鍵值作爲標準的純屬性獲取,如下:
{
"name":"My bean",
"attr2":"val2",
"attr1":"val1"
}
測試:
@Test
public void whenSerializingUsingJsonAnyGetter_thenCorrect() throws JsonProcessingException {
final ExtendableBean bean = new ExtendableBean("My bean");
bean.add("attr1", "val1");
bean.add("attr2", "val2");
String result = new ObjectMapper().writeValueAsString(bean);
System.out.println(result);
}
我們還可以使用啓用爲false的可選參數來禁用@JsonAnyGetter()。在這種情況下,地圖將轉換爲JSON,並在序列化後顯示在properties變量下。{"name":"My bean","properties":{"attr2":"val2","attr1":"val1"}}
2.2 @JsonGetter
@JsonGetter註解是@JsonProperty註解的替代方法,用於將方法標記爲getter方法。
在以下示例中,我們將方法getTheName()指定爲MyBean實體的name屬性的getter方法:
public class MyBean {
private int id;
private String name;
public MyBean() {
}
public MyBean(final int id, final String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@JsonGetter("name")
public String getTheName() {
return name;
}
@JsonSetter("name")
public void setTheName(String name) {
this.name = name;
}
}
測試:
@Test
public void whenSerializingUsingJsonGetter_thenCorrect()
throws JsonProcessingException {
MyBean bean = new MyBean(1, "My bean");
String result = new ObjectMapper().writeValueAsString(bean);
System.out.println(result);
}
// {"id":1,"name":"My bean"}
因爲這裏
name
屬性是私有的,且get和set方法名不是使用get/set+屬性名。而jackson在序列化的時候,如果是私有屬性會調用它的get方法,默認的get方法名就是get+屬性名
。如果不使用@JsonGetter註解指定,jackson會認爲theName是一個屬性。輸出如下:
{"id":1,"theName":"My bean"}
2.3 @JsonPropertyOrder
我們可以使用@JsonPropertyOrder註解指定序列化屬性的順序。讓我們爲MyBean實體的屬性設置自定義順序:
@JsonPropertyOrder({ "name", "id" })
public class MyBean {
public int id;
public String name;
}
測試輸出如下:
{"name":"My bean","id":1}
我們還可以使用@JsonPropertyOrder(alphabetic = true)
按字母順序對屬性進行排序。在這種情況下,序列化的輸出將是:{"id":1,"name":"My bean"}
2.4 @JsonRawValue
@JsonRawValue註解可以使Jackson完全按原樣序列化屬性。
在以下示例中,我們使用@JsonRawValue嵌入一些自定義JSON作爲實體的值:
public class RawBean {
public String name;
@JsonRawValue
public String json;
public RawBean() {}
public RawBean(final String name, final String json) {
this.name = name;
this.json = json;
}
}
測試:
@Test
public void whenSerializingUsingJsonRawValue_thenCorrect() throws JsonProcessingException {
final RawBean bean = new RawBean("My bean", "{\"attr\":false}");
final String result = new ObjectMapper().writeValueAsString(bean);
System.out.println(result);
}
// {"name":"My bean","json":{"attr":false}}
// 如果不加@JsonRawValue註解;輸出爲:{"name":"My bean","json":"{\"attr\":false}"}
我們還可以使用可選的布爾參數值(value)來定義此註解是否起作用。
2.5 @JsonValue
@JsonValue註解的作用是告訴jackson序列化類實例時使用它標註的的單個方法。
例如,在一個枚舉中,我們用@JsonValue註釋getName,以便任何這樣的實體都通過其名稱序列化:
public enum TypeEnumWithValue {
TYPE1(1, "Type A"),
TYPE2(2, "Type 2");
private Integer id;
private String name;
TypeEnumWithValue(Integer id, String name) {
this.id = id;
this.name = name;
}
@JsonValue
public String getName() {
return name;
}
}
測試:
@Test
public void whenSerializingUsingJsonValue_thenCorrect()
throws JsonParseException, IOException {
String enumAsString = new ObjectMapper()
.writeValueAsString(TypeEnumWithValue.TYPE1);
System.out.println(enumAsString);
}
// "Type A"
如果不使用@JsonValue標記,枚舉序列化出來的是"TYPE1"
2.6 @JsonRootName
@JsonRootName的作用可以理解爲,在序列化好的json串外面再包裹一層。
假設之前我們的序列化之後是這樣的:{ "id": 1, "name": "John" }
使用@JsonRootName包裹一層會變成這樣
{ "user": { "id": 1, "name": "John" } }
看一下如何使用:
@JsonRootName(value = "user")
public class UserWithRoot {
public int id;
public String name;
}
從Jackson 2.4開始,新的可選參數名稱空間可用於XML等數據格式。如果添加它,它將成爲完全限定名稱的一部分:
@JsonRootName(value = "user", namespace="users")
public class UserWithRootNamespace {
public int id;
public String name;
// ...
}
xml效果是這樣的
<user xmlns="users">
<id xmlns="">1</id>
<name xmlns="">John</name>
<items xmlns=""/>
</user>
2.7 @JsonSerialize
@JsonSerialize表示在序列化實體時要使用的自定義序列化程序。
讓我們看一個簡單的例子。我們將使用@JsonSerialize通過CustomDateSerializer來序列化eventDate屬性:
public class EventWithSerializer {
public String name;
@JsonSerialize(using = CustomDateSerializer.class)
public Date eventDate;
}
這是簡單的自定義Jackson序列化器:
public class CustomDateSerializer extends StdSerializer<Date> {
private static final long serialVersionUID = -2894356342227378312L;
private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
public CustomDateSerializer() {
this(null);
}
public CustomDateSerializer(final Class<Date> t) {
super(t);
}
@Override
public void serialize(Date date,
JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(formatter.format(date));
}
}
讓我們測試下:
@Test
public void whenSerializingUsingJsonSerialize_thenCorrect()
throws JsonProcessingException {
Date date = new Date();
EventWithSerializer event = new EventWithSerializer("party", date);
String result = new ObjectMapper().writeValueAsString(event);
System.out.println(result);
}
// {"name":"party","eventDate":"24-02-2020 02:34:26"}
3 Jackson反序列化註解
3.1 @JsonCreator
我們可以使用@JsonCreator註解來調整反序列化中使用的構造函數/工廠。
當我們需要反序列化某些與我們需要獲取的目標實體不完全匹配的JSON時,這非常有用。
讓我們看一個例子;假設我們需要反序列化的JSON如下:
{
"id":1,
"theName":"My bean"
}
但是,我們的目標實體中沒有theName
字段,只有一個name
字段。現在,我們不想更改實體本身,我們只需要對解組過程進行更多控制,通過使用@JsonCreator註釋構造函數並同時使用@JsonProperty註釋:
public class BeanWithCreator {
public int id;
public String name;
@JsonCreator
public BeanWithCreator(
@JsonProperty("id") int id,
@JsonProperty("theName") String name) {
this.id = id;
this.name = name;
}
}
測試
@Test
public void whenDeserializingUsingJsonCreator_thenCorrect()
throws IOException {
String json = "{\"id\":1,\"theName\":\"My bean\"}";
BeanWithCreator bean = new ObjectMapper()
.readerFor(BeanWithCreator.class)
.readValue(json);
System.out.println(bean.name);
}
// My bean
// 如果不使用,會報錯。
3.2 @JacksonInject
@JacksonInject表示該屬性將從注入中獲取而不是從JSON數據獲取其值。
public class BeanWithInject {
@JacksonInject
public int id;
public String name;
public BeanWithInject() {
}
public BeanWithInject(final int id, final String name) {
this.id = id;
this.name = name;
}
}
測試如下:
@Test
public void whenDeserializingUsingJsonInject_thenCorrect()
throws IOException {
String json = "{\"name\":\"My bean\"}";
// 使用jackson的InjectableValues類進行注入
InjectableValues inject = new InjectableValues.Std()
.addValue(int.class, 1);
BeanWithInject bean = new ObjectMapper()
.reader(inject)
.forType(BeanWithInject.class)
.readValue(json);
System.out.println(bean);
}
// BeanWithInject{id=1, name='My bean'}
3.3 @JsonAnySetter
@JsonAnySetter使我們可以靈活地使用Map作爲標準屬性。反序列化時,JSON的屬性將簡單地添加到地圖中。和之前介紹的@JsonAnyGetter正好相反。
public class ExtendableBean {
public String name;
private Map<String, String> properties;
@JsonAnySetter
public void add(String key, String value) {
properties.put(key, value);
}
}
假設我們的json是這樣的:
{
"name":"My bean",
"attr2":"val2",
"attr1":"val1"
}
那麼
attr2
和attr1
會注入到Map中。
3.4 @JsonSetter
和之前介紹的@JsonGetter相反,不做過多介紹。
3.5 @JsonDeserialize
這個是用來指定自定義的反序列化規則的。
讓我們來看一個例子,我們將使用@JsonDeserialize與CustomDateDeserializer反序列化eventDate屬性:
public class EventWithSerializer {
public String name;
@JsonDeserialize(using = CustomDateDeserializer.class)
@JsonSerialize(using = CustomDateSerializer.class)
public Date eventDate;
}
自定義的反序列化器:
public class CustomDateDeserializer extends StdDeserializer<Date> {
private static final long serialVersionUID = -5451717385630622729L;
private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(final Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
final String date = jsonParser.getText();
try {
return formatter.parse(date);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
測試:
@Test
public void whenDeserializingUsingJsonDeserialize_thenCorrect()
throws IOException {
String json = "{\"name\":\"party\",\"eventDate\":\"02-02-2020 02:30:00\"}";
EventWithSerializer event = new ObjectMapper()
.readerFor(EventWithSerializer.class)
.readValue(json);
System.out.println(event);
}
// EventWithSerializer{name='party', eventDate=Sun Feb 02 02:30:00 CST 2020}
3.6 @JsonAlias
@JsonAlias在反序列化期間爲屬性定義一個或多個備用名稱。
讓我們用一個簡單的例子看看這個註解是如何工作的:
public class AliasBean {
@JsonAlias({ "fName", "f_name" })
private String firstName;
private String lastName;
}
在這裏,我們有一個POJO,我們想將JSON中的fName、f_name或firstName屬性的值反序列化到POJO的firstName變量中。
測試如下:
@Test
public void whenDeserializingUsingJsonAlias_thenCorrect() throws IOException {
String json = "{\"fName\": \"John\", \"lastName\": \"Green\"}";
AliasBean aliasBean = new ObjectMapper().readerFor(AliasBean.class).readValue(json);
System.out.println(aliasBean);
}
// AliasBean{firstName='John', lastName='Green'}
4 Jackson屬性包含註解
4.1 @JsonIgnoreProperties
@JsonIgnoreProperties是一個類級別的註解,用於標記Jackson將忽略的一個屬性或一系列屬性。
讓我們看一個簡單的示例,忽略序列化中的屬性ID:
@JsonIgnoreProperties({ "id" })
public class BeanWithIgnore {
public int id;
public String name;
}
4.2 @JsonIgnore
@JsonIgnore批註用於在字段級別標記要忽略的屬性。
public class BeanWithIgnore {
@JsonIgnore
public int id;
public String name;
}
4.3 @JsonIgnoreType
@JsonIgnoreType將帶註解類的所有屬性標記爲忽略。
public class User {
public int id;
public Name name;
@JsonIgnoreType
public static class Name {
public String firstName;
public String lastName;
}
}
4.4 @JsonInclude
我們可以使用@JsonInclude排除具有
empty/null/default values
的屬性。
// 從序列化中排除空值:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyBean {
public int id;
public String name;
}
4.5 @JsonAutoDetect
@JsonAutoDetect可以覆蓋默認語義,即哪些屬性可見,哪些屬性不可見。
讓我們來看一個簡單的示例,該註解如何幫助我們讓私有屬性可序列化:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class PrivateBean {
private int id;
private String name;
public PrivateBean() {}
public PrivateBean(final int id, final String name) {
this.id = id;
this.name = name;
}
}
測試:
@Test
public void whenSerializingUsingJsonAutoDetect_thenCorrect()
throws JsonProcessingException {
PrivateBean bean = new PrivateBean(1, "My bean");
String result = new ObjectMapper()
.writeValueAsString(bean);
System.out.println(result);
}
// {"id":1,"name":"My bean"}
這樣,私有屬性沒有get方法也可以被序列化了。
5 Jackson多態類型處理註解
接下來–讓我們看一下Jackson的多態類型處理註釋:
- @JsonTypeInfo - 指示要在序列化中包含哪些類型信息的詳細信息
- @JsonSubTypes - 指示帶註解類型的子類型
- @JsonTypeName - 定義用於註解類的邏輯類型名稱
讓我們看一個複雜的示例,使用@JsonTypeInf
o,@ JsonSubTypes
和@JsonTypeName
三個註解序列化和反序列化實體Zoo
:
public class Zoo {
public Animal animal;
public Zoo() {}
public Zoo(final Animal animal) {
this.animal = animal;
}
/***********************以下是三個靜態內部類*********************/
public static class Animal {
public String name;
public Animal() {}
public Animal(final String name) {
this.name = name;
}
}
public static class Dog extends Animal {
public double barkVolume;
public Dog() {}
public Dog(final String name) {
this.name = name;
}
}
public static class Cat extends Animal {
boolean likesCream;
public int lives;
public Cat() {}
public Cat(final String name) {
this.name = name;
}
}
}
以上我們什麼註解都沒有加,看序列化後是什麼結果
@Test
public void whenSerializingPolymorphic_thenCorrect()
throws JsonProcessingException {
Zoo.Dog dog = new Zoo.Dog("lacy");
Zoo zoo = new Zoo(dog);
String result = new ObjectMapper()
.writeValueAsString(zoo);
System.out.println(result);
}
// {"animal":{"name":"lacy","barkVolume":0.0}}
這樣序列化後,我們只知道是一個動物,卻不知道具體是什麼動物,下面我們就利用以上三個註解進行修飾下。
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public static class Animal {
public String name;
public Animal() {}
public Animal(final String name) {
this.name = name;
}
}
@JsonTypeName("dog")
public static class Dog extends Animal {
public double barkVolume;
public Dog() {}
public Dog(final String name) {
this.name = name;
}
}
@JsonTypeName("cat")
public static class Cat extends Animal {
boolean likesCream;
public int lives;
public Cat() {}
public Cat(final String name) {
this.name = name;
}
}
我們在
Animal
類上加上以上註解,再看一下序列化後的結果
{"animal":{"type":"dog","name":"lacy","barkVolume":0.0}}
我們發現爲我們多加了一個type
屬性。
下面試一下反序列化
@Test
public void whenDeserializingPolymorphic_thenCorrect()
throws IOException {
String json = "{\"animal\":{\"name\":\"lacy\",\"type\":\"cat\"}}";
// {"animal":{"name":"lacy","type":"cat","likesCream":false,"lives":2}}
Zoo zoo = new ObjectMapper()
.readerFor(Zoo.class)
.readValue(json);
assertEquals("lacy", zoo.animal.name);
assertEquals(Zoo.Cat.class, zoo.animal.getClass());
}
// 可以正常執行通過。
如果將
String json = "{\"animal\":{\"name\":\"lacy\",\"type\":\"cat\"}}";
改爲String json = "{\"animal\":{\"name\":\"lacy\",\"type\":\"dog\"}}";
就會報錯。
6 Jackson其他註解
6.1 @JsonProperty
我們可以添加@JsonProperty註解在JSON中指示屬性名稱。可以看做是@JsonGetter和@JsonSetter的組合版
在處理非標準的getter和setter時,我們可以使用@JsonProperty來序列化/反序列化屬性名:
public class MyBean {
public int id;
private String name;
@JsonProperty("name")
public void setTheName(String name) {
this.name = name;
}
@JsonProperty("name")
public String getTheName() {
return name;
}
}
6.2 @JsonFormat
@JsonFormat註解指定序列化時間類型的格式。
public class EventWithFormat {
public String name;
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "dd-MM-yyyy hh:mm:ss")
public Date eventDate;
}
經測試,@JsonFormat
對java8新增的時間類型LocalDateTime等,不適用。
6.3 @JsonUnwrapped
@JsonUnwrapped定義在序列化/反序列化時應該解包/展平的值。
public class UnwrappedUser {
public int id;
@JsonUnwrapped
public Name name;
public UnwrappedUser() {}
public UnwrappedUser(final int id, final Name name) {
this.id = id;
this.name = name;
}
public static class Name {
public String firstName;
public String lastName;
public Name() {
}
public Name(final String firstName, final String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
}
序列化測試:
@Test
public void whenSerializingUsingJsonUnwrapped_thenCorrect()
throws JsonProcessingException {
UnwrappedUser.Name name = new UnwrappedUser.Name("John", "Doe");
UnwrappedUser user = new UnwrappedUser(1, name);
String result = new ObjectMapper().writeValueAsString(user);
System.out.println(result);
}
// {"id":1,"firstName":"John","lastName":"Doe"}
反序列化測試:
@Test
public void whenDeserializingUsingJsonUnwrapped_thenCorrect()
throws JsonProcessingException {
String json = "{\"id\":1,\"firstName\":\"John\",\"lastName\":\"Doe\"}";
String json1 = "{\"id\":1,\"name\":{\"firstName\":\"John\",\"lastName\":\"Doe\"}}";
UnwrappedUser bean = new ObjectMapper()
.readerFor(UnwrappedUser.class)
.readValue(json1);
assertEquals("John",bean.name.firstName);
}
// 經測試,json1形式的反序列化後,name屬性是沒有值的,所以使用@JsonUnwrapped註解後,反序列化時需要注意
6.4 @JsonView
@JsonView表示包含用於序列化/反序列化的屬性的視圖。也就是我們可以通過@JsonView的方式指定需要序列化那些屬性。
// 定義一個視圖類
public class Views {
public static class Public {}
public static class Internal extends Public {}
}
public class Item {
@JsonView(Views.Public.class)
public int id;
@JsonView(Views.Public.class)
public String itemName;
@JsonView(Views.Internal.class)
public String ownerName;
}
測試如下:
@Test
public void whenSerializingUsingJsonView_thenCorrect()
throws JsonProcessingException {
Item item = new Item(2, "book", "John");
String result = new ObjectMapper()
.writerWithView(Views.Public.class)
.writeValueAsString(item);
System.out.println(result);
String result2 = new ObjectMapper()
.writerWithView(Views.Internal.class)
.writeValueAsString(item);
System.out.println(result2);
}
/*
{"id":2,"itemName":"book"}
{"id":2,"itemName":"book","ownerName":"John"}
*/
6.5 @JsonManagedReference, @JsonBackReference
@JsonManagedReference和@JsonBackReference可以解決嵌套關係和循環問題
首先先看這麼兩個類
public class ItemWithRef {
public int id;
public String itemName;
public UserWithRef owner;
}
public class UserWithRef {
public int id;
public String name;
public List<ItemWithRef> userItems;
}
這兩個類中的屬性都有各自的屬性。假設我們不做約束,看看序列化會有什麼結果
@Test
public void whenSerializingUsingJacksonReferenceAnnotation_thenCorrect()
throws JsonProcessingException {
UserWithRef user = new UserWithRef(1, "John");
ItemWithRef item = new ItemWithRef(2, "book", user);
user.addItem(item);
String result = new ObjectMapper().writeValueAsString(item);
System.out.println(result);
}
// 此時會報錯會報一個很長很長的錯誤。這裏就不貼出來了。
我們爲兩個類加上上面兩個註解再試一次,看看會怎麼樣
public class ItemWithRef {
public int id;
public String itemName;
@JsonManagedReference
public UserWithRef owner;
}
public class UserWithRef {
public int id;
public String name;
@JsonBackReference
public List<ItemWithRef> userItems;
}
這次就可以正常序列化了{"id":2,"itemName":"book","owner":{"id":1,"name":"John"}}
**注意:**直接序列化那個對象的屬性上標註
@JsonManagedReference
6.6 @JsonIdentityInfo
@JsonIdentityInfo表明在序列化/反序列化時應該使用對象標識——例如,處理無限遞歸類型的問題。
看下面類似6.5的例子
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class ItemWithIdentity {
public int id;
public String itemName;
public UserWithIdentity owner;
}
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class UserWithIdentity {
public int id;
public String name;
public List<ItemWithIdentity> userItems;
}
測試如下:
@Test
public void whenSerializingUsingJsonIdentityInfo_thenCorrect()
throws JsonProcessingException {
UserWithIdentity user = new UserWithIdentity(1, "John");
ItemWithIdentity item = new ItemWithIdentity(2, "book", user);
user.addItem(item);
String result = new ObjectMapper().writeValueAsString(item);
System.out.println(result);
}
// {"id":2,"itemName":"book","owner":{"id":1,"name":"John","userItems":[2]}}
/*
{
"id": 2,
"itemName": "book",
"owner": {
"id": 1,
"name": "John",
"userItems": [
2
]
}
}
*/
注意:這裏的結果和6.5中的不一樣哦
- 6.5中
owner
屬性中少了userItems
屬性- 這裏
owner
屬性中的userItems
中使用id來標識。
6.7 @JsonFilter
@JsonFilter註解指定在序列化期間使用的過濾器。
看一個例子:
@JsonFilter("myFilter")
public class BeanWithFilter {
public int id;
public String name;
}
序列化時:
@Test
public void whenSerializingUsingJsonFilter_thenCorrect()
throws JsonProcessingException {
BeanWithFilter bean = new BeanWithFilter(1, "My bean");
// 這裏添加了一個名爲`myFilter`的過濾器,作用是:除了`name`屬性,其他的都排除在外
FilterProvider filters
= new SimpleFilterProvider().addFilter(
"myFilter",
SimpleBeanPropertyFilter.filterOutAllExcept("name"));
String result = new ObjectMapper()
.writer(filters)
.writeValueAsString(bean);
System.out.println(result);
}
// {"name":"My bean"}
7 自定義Jackson註解
接下來,讓我們看看如何創建自定義Jackson註解。這裏我們需要使用@JacksonAnnotationsInside註解:
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({ "name", "id", "dateCreated" })
public @interface CustomAnnotation {}
// 說是自定義,其實就是使用Jackson原有的註解,將其進行組合,這個註解的作用:忽略空值屬性,並按照"name", "id", "dateCreated"排序。
使用
@CustomAnnotation
public class BeanWithCustomAnnotation {
public int id;
public String name;
public Date dateCreated;
}
測試下:
@Test
public void whenSerializingUsingCustomAnnotation_thenCorrect()
throws JsonProcessingException {
BeanWithCustomAnnotation bean
= new BeanWithCustomAnnotation(1, "My bean", null);
String result = new ObjectMapper().writeValueAsString(bean);
System.out.println(result);
}
/*
{
"name":"My bean",
"id":1
}
*/
8 Jackson MixIn 註解
看下面的例子
public class Item2 {
public int id;
public String itemName;
public User owner;
}
@JsonIgnoreType
public class MyMixInForIgnoreType {}
序列化時:
@Test
public void whenSerializingUsingMixInAnnotation_thenCorrect()
throws JsonProcessingException {
User u = new User(2,"John");
Item2 item = new Item2(1, "book", u);
String result = new ObjectMapper().writeValueAsString(item);
System.out.println(result);
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(User.class, MyMixInForIgnoreType.class); // 將User列爲忽略的類型
String result2 = mapper.writeValueAsString(item);
System.out.println(result2);
}
/*
{"id":1,"itemName":"book","owner":{"id":2,"name":"John"}}
{"id":1,"itemName":"book"}
*/
9. 禁用Jackson註解
ObjectMapper mapper = new ObjectMapper();
mapper.disable(MapperFeature.USE_ANNOTATIONS);
// 這樣就禁用了註解
看一個例子
@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({ "name", "id" })
public class MyBean {
public int id;
public String name;
}
MyBean bean = new MyBean(1, null);
如果不禁用註解序列化爲:
{"id":1}
禁用註解後的結果爲:
{
"id":1,
"name":null
}