Jackson

Jackson是一个基于Java的、性能较高且简单易用的序列化和反序列化JSON的开源框架,Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。
  Spring MVC的默认JSON解析器也是Jackson。
  优点:
    1)依赖的jar包较少,简单易用
    2)解析大的JSON文件速度比较快
    3)Jackson运行时占用内存比较低,性能比较好
    4)Jackson有灵活的API,可以很容易进行扩展和定制
 
  Jackson 的核心模块由三部分组成
    1、jackson-core,核心包,提供基于”流模式”解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json
    2、jackson-annotations,注解包,提供标准注解功能
    3、jackson-databind ,数据绑定包, 提供基于”对象绑定” 解析的相关 API ( ObjectMapper ) 和”树模型” 解析的相关 API (JsonNode);基于”对象绑定” 解析的 API 和”树模型”解析的 API 依赖基于”流模式”解析的 API
 
 
Jackson的使用

Jackson 引入依赖的jar包:

        <!--jackson-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.1</version>
        </dependency>

   jackson-databind 依赖 jackson-core 和 jackson-annotations,根据依赖传递性,当添加 jackson-databind 之后, jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中,因此无需再单独添加jackson-core 和 jackson-annotations

简单用法使用步骤:

  第1步:创建ObjectMapper对象

    创建ObjectMapper对象。它是一个可重复使用的对象。
    ObjectMapper mapper = new ObjectMapper();

  第2步:反序列化JSON到对象

    从JSON对象使用readValue()方法来获取。通过JSON字符串和对象类型作为参数JSON字符串/来源。
    //Object to JSON Conversion
    Student student = mapper.readValue(jsonString, Student.class);

  第3步:序列化对象到JSON

    使用writeValueAsString()方法来获取对象的JSON字符串表示。
    //Object to JSON Conversion
    jsonString = mapper.writeValueAsString(student);

ObjectMapper

  ObjectMapper类是Jackson库的主要类。它提供一些功能将转换成Java对象匹配JSON结构,反之亦然。它使用JsonParser和JsonGenerator的实例实现JSON实际的读/写

   1)ObjectMapper 通过 writeValue 系列方法 将 java 对 象序列化 为 json,并 将 json 存 储成不同的格式,String(writeValueAsString),Byte Array(writeValueAsString),Writer, File,OutStream 和 DataOutput。

   2)ObjectMapper 通过 readValue 系列方法从不同的数据源像 String , Byte Array, Reader,File,URL, InputStream 将 json 反序列化为 java 对象

ObjectMapper 的一些相关配置:

//在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
    false);
 //在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
 mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
 //在序列化时忽略值为 null 的属性
 mapper.setSerializationInclusion(Include.NON_NULL);
 //忽略值为默认值的属性
 mapper.setDefaultPropertyInclusion(Include.NON_DEFAULT);

 Jackson的注解使用

注解用法
@JsonProperty 用于属性,把属性的名称序列化时转换为另外一个名称。示例: @JsonProperty(“birth_ d ate”) private Date birthDate;
@JsonFormat 用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例: @JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm”) public Date getBirthDate()
@JsonPropertyOrder 用于类, 指定属性在序列化时 json 中的顺序 , 示例: @JsonPropertyOrder({ “birth_Date”, “name” }) public class Person
@JsonCreator 用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。 示例: @JsonCreator public Person(@JsonProperty(“name”)String name) {…}
@JsonAnySetter 用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中 @JsonAnySetter public void set(String key, Object value) { map.put(key, value); }
@JsonAnyGetter 用于方法 ,获取所有未序列化的属性 public Map<string, object> any() { return map; }

泛型反序列化

  对于 List 类型 ,可以调用 constructCollectionType 方法来序列化,也可以构造 TypeReference 来序列化

 CollectionType javaType = mapper.getTypeFactory().constructCollectionType(List.class,Person.class);
 List<Person> personList = mapper.readValue(jsonInString,javaType);
 List<Person> personList = mapper.readValue(jsonInString, new TypeReference<List<Person>>(){});

  map 类型, 与 List 的实现方式相似,Map 泛型使用示例:

//第二参数是 map 的 key 的类型,第三参数是 map 的 value 的类型
 MapType javaType =mapper.getTypeFactory().constructMapType(HashMap.class,String.class,Person.class);
 Map<String, Person> personMap = mapper.readValue(jsonInString,javaType);
 Map<String, Person> personMap = mapper.readValue(jsonInString, new TypeReference<Map<String, Person>>() {});

属性可视化

  默认的属性可视化规则如下:

  1)若该属性修饰符是 public,该属性可序列化和反序列化

  2)若属性的修饰符不是 public,但是它的 getter 方法和 setter 方法是 public,该属性可序列化和反序列化。因为 getter 方法用于序列化, 而 setter 方法用于反序列化

  3)若属性只有 public 的 setter 方法,而无 public 的 getter 方 法,该属性只能用于反序列化

  若想更改默认的属性可视化的规则,需要调用 ObjectMapper 的方法 setVisibility。

  如使修饰符为protected的属性name也可以序列化和反序列化:

mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

 public class Person {
    public int age;
    protected String name;
   }

 // PropertyAccessor 支持的类型有: ALL,CREATOR,FIELD,GETTER,IS_GETTER,NONE,SETTER
 //  Visibility 支持的类型有: ANY,DEFAULT,NON_PRIVATE,NONE,PROTECTED_AND_PUBLIC,PUBLIC_ONLY

属性过滤

  在将Java对象序列化为json时,有些属性需要过滤掉,不显示在json中,Jackson有多种实现方法:

  1、注解方式,可以用 @JsonIgnore 过滤单个属性或用 @JsonIgnoreProperties 过滤多个属性

 @JsonIgnore
 public int getAge()

 @JsonIgnoreProperties(value = { "age","birth_date" })
 public class Person{...}

  2、addMixIn 方法加注解方式@JsonIgnoreProperties

    public ObjectMapper addMixIn(Class<?> target, Class<?> mixinSource);

    addMixIn 方法的作用是用 mixinSource 接口或类的注解会重写 target 或 target 的子类型的注解

  3、SimpleBeanPropertyFilter 方式。这种方式比前两种方式更加灵活,也更复杂一些

    1)首先需要设置@JsonFilter 类或接口,

    2)其次设置 addMixIn,将@JsonFilter 作用于 java 对象上,

    3)最后调用 SimpleBeanPropertyFilter 的 serializeAllExcept 方法或重写 SimpleBeanPropertyFilter 的 serializeAsField 方法来过滤相关属性

//设置 Filter 类或接口
    @JsonFilter("myFilter")
    public interface MyFilter {...}

    //设置 addMixIn
    mapper.addMixIn(Person.class, MyFilter.class);

    //调用 SimpleBeanPropertyFilter 的 serializeAllExcept 方法
    SimpleBeanPropertyFilter newFilter = SimpleBeanPropertyFilter.serializeAllExcept("age");
    //或重写 SimpleBeanPropertyFilter 的 serializeAsField 方法
    SimpleBeanPropertyFilter newFilter = new SimpleBeanPropertyFilter() {
        @Override
        public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception {
            if (!writer.getName().equals("age")) {
                writer.serializeAsField(pojo, jgen, provider);
            }
        }
    };

    //设置 FilterProvider
    FilterProvider filterProvider = new SimpleFilterProvider().addFilter("myFilter", newFilter);
    mapper.setFilterProvider(filterProvider).writeValueAsString(person);
View Code

自定义序列化和反序列化

  自定义的序列化类需要直接或间接继承StdSerializer 或 JsonSerializer,同时需要利用 JsonGenerator 生成 json,重写方法 serialize,如自定义序列化:

public class CustomSerializer extends StdSerializer<Person> {
        @Override
        public void serialize(Person person, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeNumberField("age", person.getAge());
            jsonGenerator.writeStringField("name", person.getName());
            jsonGenerator.writeEndObject();
        }
    }
View Code

  定义好自定义序列化类和自定义反序列化类,若想在程序中调用它们,还需要注册到 ObjectMapper 的 Module,示例如下:

    SimpleModule module = new SimpleModule("myModule");
    module.addSerializer(new CustomSerializer(Person.class));
    module.addDeserializer(Person.class,new CustomDeserializer());
    // 注册module到mapper
    mapper.registerModule(module);
    // 也可通过注解方式加在java对象的属性,方法或类上面来调用它们,
    @JsonSerialize(using = CustomSerializer.class)
    @JsonDeserialize(using = CustomDeserializer.class)
    public class Person{...}
View Code

   Spring中对某个bean自定义序列化方式:

/**
 * TimeOfDay 自定义序列化和反序列化
 *
 * @author yangyongjie
 */
@JsonComponent
public class CustomTimeOfDaySerializerAndDeserializer {

    public static class TimeOfDaySerializer extends JsonSerializer<TimeOfDay> {
        @Override
        public void serialize(TimeOfDay timeOfDay, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.HOUR_OF_DAY, timeOfDay.getHour());
            cal.set(Calendar.MINUTE, timeOfDay.getMinute());
            cal.set(Calendar.SECOND, timeOfDay.getSecond());
            jsonGenerator.writeNumber(cal.getTimeInMillis());
        }
    }

    public static class TimeOfDayDeserializer extends JsonDeserializer<TimeOfDay> {
        @Override
        public TimeOfDay deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
            return TimeOfDay.hourAndMinuteAndSecondFromDate(deserializationContext.readValue(jsonParser, Date.class));
        }
    }

}
View Code

工具类

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.MapType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

/**
 * Jackson工具类
 *
 * @author yangyongjie
 * @date 2020/3/20
 * @desc
 */
public class JacksonUtil {

    /**
     * ObjectMapper 对象可重复使用
     */
    private static final ObjectMapper MAPPER;

    static {
        MAPPER = new ObjectMapper();
        // 忽略JSON字符串有的,而反序列化的Java对象没有的属性
        MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(JacksonUtil.class);

    private JacksonUtil() {
    }

    /**
     * 对象转换为jsonString
     *
     * @param obj
     * @return
     */
    public static String toString(Object obj) {
        return toString(obj, "");
    }

    /**
     * 对象转换为jsonString
     *
     * @param obj
     * @param defaultString
     * @return
     */
    public static String toString(Object obj, String defaultString) {
        try {
            return MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            LOGGER.error("writeValueAsString:" + e.getMessage(), e);
        }
        return defaultString;
    }

    /**
     * 反序列化为对象,不带泛型
     *
     * @param jsonString
     * @param tClass
     * @param <T>
     * @return
     */
    public static <T> T toObject(String jsonString, Class<T> tClass) {
        return toObject(jsonString, null, tClass);
    }

    /**
     * 反序列化为对象,不带泛型
     *
     * @param jsonString
     * @param defaultValue
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T toObject(String jsonString, T defaultValue, Class<T> clazz) {
        try {
            return MAPPER.readValue(jsonString, clazz);
        } catch (Exception e) {
            LOGGER.error("readValue:" + e.getMessage(), e);
        }
        return defaultValue;
    }

    /**
     * 反序列化为对象,带泛型
     *
     * @param jsonString
     * @param typeReference
     * @param <T>
     * @return
     */
    public static <T> T toObject(String jsonString, TypeReference<T> typeReference) {
        return toObject(jsonString, null, typeReference);
    }

    /**
     * 反序列化为对象,带泛型
     *
     * @param jsonString
     * @param defaultValue
     * @param typeReference
     * @return
     */
    public static <T> T toObject(String jsonString, T defaultValue, TypeReference<T> typeReference) {
        try {
            return MAPPER.readValue(jsonString, typeReference);
        } catch (Exception e) {
            LOGGER.error("readValue:" + e.getMessage(), e);
        }
        return defaultValue;
    }

    /**
     * 反序列化对象,返回list
     *
     * @param jsonString
     * @param clazz
     * @param <T>        List中元素的泛型
     * @return
     */
    public static <T> List<T> ofList(String jsonString, Class<T> clazz) {

        if (StringUtils.isBlank(jsonString)) {
            return null;
        }
        CollectionType javaType = MAPPER.getTypeFactory().constructCollectionType(List.class, clazz);
        try {
            return MAPPER.readValue(jsonString, javaType);
        } catch (JsonProcessingException e) {
            LOGGER.error("ofList:" + e.getMessage(), e);
        }
        return null;
    }

    /**
     * 反序列化为对象,带泛型
     *
     * @param jsonString
     * @param typeReference
     * @param <T>           代表List本身的泛型
     * @return
     */
    public static <T> T ofList(String jsonString, TypeReference<T> typeReference) {

        if (StringUtils.isBlank(jsonString)) {
            return null;
        }
        try {
            return MAPPER.readValue(jsonString, typeReference);
        } catch (JsonProcessingException e) {
            LOGGER.error("ofList:" + e.getMessage(), e);
        }
        return null;
    }
    
    /**
     * 反序列化对象,返回map
     *
     * @param jsonString
     * @param keyClazz
     * @param valueClazz
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> Map<K, V> ofMap(String jsonString, Class<K> keyClazz, Class<V> valueClazz) {
        if (StringUtils.isBlank(jsonString)) {
            return null;
        }
        MapType javaType = MAPPER.getTypeFactory().constructMapType(Map.class, keyClazz, valueClazz);
        try {
            return MAPPER.readValue(jsonString, javaType);
        } catch (JsonProcessingException e) {
            LOGGER.error("ofMap:" + e.getMessage(), e);
        }
        return null;
    }

}

参考:

https://developer.ibm.com/zh/articles/jackson-advanced-application/

http://tutorials.jenkov.com/java-json/index.html

END.

原文地址:https://www.cnblogs.com/yangyongjie/p/14313741.html