zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    互联网、云大数据相关书籍推荐
    育儿、教育书籍推荐
    MySQL客户端工具的选择
    解决Windows10或者其他版本Windows Update报错的问题
    启动Myeclipse报错“Failed to create the Java Virtual Machine”的解决办法
    mysql的日期存储字段比较int,datetime,timestamp区别
    nginx增加ssl服务方法
    mysql导入出现MySQL Error 1153
    mysql忘记密码修改方法
    清空本地ssh记录数据,ssh: connect to host Ip port 22: Connection refused
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/14313741.html
Copyright © 2011-2022 走看看