最近因为工程需要,为了提高一些数据性能,决定替换掉底层一部分使用已久的json-lib库,换成Jackson,以求提高一些性能。
但是Jackson感觉文档和案例都不怎么齐全,而且功能又十分复杂,为了实现一些常用的功能,摸索了相当长一段时间。
目前实际使用中需要的大部分问题都已经解决,把一些很可能常用的功能整理一下贴出来,给大家分享一下经验。
实际可能的需求:
1. 不能修改原有的类;
2. 对一个bean的全部或者指定的一部分属性进行json序列化;
3. 调整输出的日期格式;
4. 对某些输出值做简单选择。
示例代码如下:
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
public class TestJackson {
public static class Person {
private String name;
private Date birthDate;
private String gender;
public Person() {};
public Person(String name, Date birthDate, String gender) {
super();
this.name = name;
this.birthDate = birthDate;
this.gender = gender;
}
public String getName() {
return name;
}
public Date getBirthDate() {
return birthDate;
}
public String getGender() {
return gender;
}
public String toString() {
return String.format("%s, %s, %s", name, birthDate, gender);
}
}
@Test
public void testUp() throws JsonGenerationException, JsonMappingException, IOException{
Person p1 = new Person("Jack", new Date(), "Male");
Person p2 = new Person("Mary", null, "");
//定义一个BeanPropertyFilter,滤掉birthDate属性。
//以Person.class.getName()为id将该过滤器注册到一个SimpleFilterProvider里
FilterProvider filters = new SimpleFilterProvider()
.addFilter(Person.class.getName(),
SimpleBeanPropertyFilter.serializeAllExcept("birthDate")
);
ObjectMapper om = new ObjectMapper();
//设置输出所有的非null属性值
om.setSerializationInclusion(Include.NON_NULL);
//设置输出的日期类型格式
om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
//注意:自定义一个JacksonAnnotationIntrospector,使得返回的filterId是被序列化的类名。
//即在序列化Person时,返回的是Person.class.getName()。
//与下面的setFilters共同作用,使得滤掉birthDate属性的功能得以实现。
//默认情况下会返回@JsonFilter的value。
//还可以自定义更加复杂的情况。
om.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
private static final long serialVersionUID = 1L;
@Override
public Object findFilterId(AnnotatedClass ac) {
return ac.getName();
}
});
om.setFilters(filters);
System.out.println(om.writeValueAsString(p1));
System.out.println(om.writeValueAsString(p2));
Person [] ps = new Person[]{p1, p2};
String str = om.writeValueAsString(ps);
System.out.println(str);
Person [] array = om.readValue(str, Person[].class);
System.out.println(array.getClass());
for(Person p : array) {
System.out.println(p);
}
List<Person> list = om.readValue(str, new TypeReference<List<Person>>(){});
System.out.println(list.getClass());
for(Person p : list) {
System.out.println(p);
}
List<Person> list2 = om.readValue(str, om.getTypeFactory().constructCollectionType(List.class, Person.class));
System.out.println(list2.getClass());
for(Person p : list2) {
System.out.println(p);
}
Set<Person> set = om.readValue(str, new TypeReference<Set<Person>>(){});
System.out.println(set.getClass());
for(Person p : set) {
System.out.println(p);
}
};
}
输出结果为: {"name":"Jack","gender":"Male"}
{"name":"Mary","gender":""}
[{"name":"Jack","gender":"Male"},{"name":"Mary","gender":""}]
class [Lme.chenqiang.util.TestJackson$Person;
Jack, null, Male
Mary, null,
class java.util.ArrayList
Jack, null, Male
Mary, null,
class java.util.Vector
Jack, null, Male
Mary, null,
class java.util.HashSet
Jack, null, Male
Mary, null,