在Jackson中Annotations是一个很棒的的方法,用于管理序列化和反序列化。然而,如果你想注解一个第三方类,这个时候你没有源码,你无法在想序列化的类中添加Annotation,或者你不想你的POJOs与Jackson Annotations紧密结合,那么其他的注解方式就无能为力了,这时Mix-In 注解就派上用场了。你只需定义一个mix-in抽象类,它是你想添加注解的实际类的代理,这样注解就可以添加到这个代理类里面。
下面为大家演示Mix-In的用法:
Example:
Bird.java
1 package com.jackson.test;
2
3 public class Bird {
4 private String name;
5 private String sound;
6 private String habitat;
7
8 public Bird(String name) {
9 this.name = name;
10 }
11
12 public String getName() {
13 return name;
14 }
15
16 public String getSound() {
17 return sound;
18 }
19
20 public String getHabitat() {
21 return habitat;
22 }
23
24 public void setSound(String sound) {
25 this.sound = sound;
26 }
27
28 public void setHabitat(String habitat) {
29 this.habitat = habitat;
30 }
31
32 @Override
33 public String toString() {
34 return "Bird [name=" + name + ", sound=" + sound + ", habitat=" + habitat + "]";
35 }
36 }
BirdMixIn.java
1 package com.jackson.test;
2
3 import com.fasterxml.jackson.annotation.JsonIgnore;
4 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 import com.fasterxml.jackson.annotation.JsonProperty;
6 import com.fasterxml.jackson.annotation.JsonView;
7
8 //@JsonIgnoreProperties({"sound"})
9 public abstract class BirdMixIn {
10 @JsonView(FilterView.OutputA.class)
11 @JsonProperty("sound")
12 String sound;
13 // abstract String getSound();
14 /* BirdMixIn(@JsonProperty("name") String name){
15
16 };
17
18 // @JsonView(FilterView.OutputA.class)
19 @JsonProperty("sound")
20 abstract String getSound();
21
22 // @JsonProperty("habitat")
23 // abstract String getHabitat();
24 */}
testMix.java
1 package com.jackson.test;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import com.fasterxml.jackson.core.JsonProcessingException;
7 import com.fasterxml.jackson.databind.MapperFeature;
8 import com.fasterxml.jackson.databind.ObjectMapper;
9
10 public class testMix {
11
12 /**
13 * @param args
14 */
15 public static void main(String[] args) {
16 // TODO Auto-generated method stub
17 ObjectMapper mapper = new ObjectMapper();
18 mapper.addMixInAnnotations(Bird.class, BirdMixIn.class);
19 List<Bird> birds = new ArrayList<Bird>();
20 Bird bird1 = new Bird("sdfd");
21 bird1.setSound("dfsa");
22 bird1.setHabitat("red");
23 birds.add(bird1);
24
25 Bird bird2 = new Bird("scarlet ibis");
26 bird2.setSound("ee");
27 bird2.setHabitat("water");
28 birds.add(bird2);
29
30 try {
31 mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
32 String json = mapper.writerWithView(FilterView.OutputA.class).writeValueAsString(birds);
33 System.out.println(json);
34 } catch (JsonProcessingException e) {
35 // TODO Auto-generated catch block
36 e.printStackTrace();
37 }
38 }
39
40 }
41
42 class FilterView {
43 static class OutputA {}
44 static class OutputB {}
45 }
Output
[{"sound":"dfsa"},{"sound":"ee"}]
在Bird
中我们定义了三个private的成员变量,但是序列化时只输出了sound
属性,在Bird类中也没有加任何的Jackson Annotation。这常用于服务器端向前端传某个对象的概略信息,比如一个对象有好几十个属性,而且很多属性的值是一个文本类型且很长,但是前端只要其中的几个属性,比如ID,topic等等。那么把整个对象序列化成json,就增大的数据传输量。解决方案有两个。
-
方案一 —— 在POJOs中添加
JsonIgnore
忽视掉不需要的属性。 这里有两个问题:一、好几十个属性中我们只要四五个,那么我们得在其余几十个属性上加JsonIgnore
,工作量太大。二、序列化对象是第三方类库的实例,我们无法在源码中添加Annotation,或者我们想保持代码简洁性,将Jackson Annotation与类声明分离。 针对第一个问题我们可以使用JsonView
注解,它的作用与JsonIgnore
相反,被JsonView
注解注解的将被序列化,那么只需在少数几个需要的属性上添加。第二个问题其他Annotation就解决不了了。 -
方案二 —— 就是采用前面的