Jackson Mix-In Annotations使用示例

  在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就解决不了了。

  • 方案二 —— 就是采用前面的