Jackson学习笔记(1)

本文介绍如何使用Jackson库实现特定的JSON序列化需求,包括忽略指定字段、调整日期格式及选择性输出等高级功能。

最近因为工程需要,为了提高一些数据性能,决定替换掉底层一部分使用已久的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,

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值