zoukankan      html  css  js  c++  java
  • Jackson的使用

    Jackson对于Java对象属性的可见性

    Jackson在序列化时会对Java对象中哪些属性进行序列化呢?主要有以下几种

    • 属性的修饰符为public
    • 属性的修饰符为private, 但是提供public的get方法
    • 对象中没有此属性, 但是类中有public的get方法

    也就是说序列化时能不能够访问到此属性, 反序列化时能不能设置此属性的值.

    注:

    1. 对于第三种情况, 键就是getXXX中的XXX, 值就是get方法的返回值
    2. 对于属性是boolean类型的, 那么该属性的get方法是isXXX. 如下:
      private boolean exist
      public boolean isExist()

    当然也可以使用@JsonIgnore注解来指定忽略那个属性, 使这个属性不参与序列化和反序列化.

    Jackson对于时间的处理

    默认情况下:

    • 对于java.util.Date、java.sql.Date、java.sql.Timestamp这些时间类, 都会序列化成一个long型的时间戳
    • 对于Java8中新的时间类, 则会序列化成一个数组, 格式为[年, 月, 日, 时, 分, 秒, 毫秒] 或者 [年, 月, 日], 当然要使用新的时间类, 需要加入jsr310模块, 在初始化时需要注册时间模块
      objectMapper.registerModule(new JavaTimeModule());

    格式化:

    1. 全局处理

    1.1 在初始化ObjectMapper时设置一个格式.
    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
    此方式对于java.util.Date、java.time.LocalDateTime、java.time.LocalDate(对于新的时间类前提是有注册过JavaTimeModule模块)都有效
    Date: 2018-10-27 14:30:30
    LocalDateTime: 2018-10-27T14:30:30.475
    LocalDate: 2018-10-27
    LocalTime:14:30:30

    1.2 使用JavaTimeModule(针对JDK8新的时间类)
    可以发现使用第一种方式后对于LocalDateTime的格式化并不完美, 可以像下面这样做

    JavaTimeModule javaTimeModule = new JavaTimeModule();
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
    javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
    objectMapper.registerModule(javaTimeModule);
    
    1. 局部处理
      对于指定的时间属性使用@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解

    一个自定义的JSON工具类

    
    package com.wangtao.util;
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.JavaType;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
    import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
    import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
    import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
    import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
    import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
    import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    import java.time.format.DateTimeFormatter;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * JSON工具类.
     * Created at 2018/9/30 11:45
     *
     * @author wangtao
     */
    public class JSONUtils {
    
        private static ObjectMapper objectMapper = new ObjectMapper();
    
        private static final String STANDARD_PATTERN = "yyyy-MM-dd HH:mm:ss";
        private static final String DATE_PATTERN = "yyyy-MM-dd";
        private static final String TIME_PATTERN = "HH:mm:ss";
    
        private static final Logger LOG = LoggerFactory.getLogger(JSONUtils.class);
    
        static {
    
            //设置java.util.Date时间类的序列化以及反序列化的格式
            objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_PATTERN));
    
            // 初始化JavaTimeModule
            JavaTimeModule javaTimeModule = new JavaTimeModule();
    
            //处理LocalDateTime
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(STANDARD_PATTERN);
            javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
            javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
    
            //处理LocalDate
            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
            javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
            javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));
    
            //处理LocalTime
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_PATTERN);
            javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter));
            javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter));
    
            //注册时间模块, 支持支持jsr310, 即新的时间类(java.time包下的时间类)
            objectMapper.registerModule(javaTimeModule);
    
            // 包含所有字段
            objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
    
            // 在序列化一个空对象时时不抛出异常
            objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    
            // 忽略反序列化时在json字符串中存在, 但在java对象中不存在的属性
            objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        }
    
        private JSONUtils() {
    
        }
    
        /**
         * 将Java对象序列化成一个JSON对象或者JSON数组.
         *
         * @param object Java对象
         * @return 返回一个JSON格式的字符串
         */
        public static String objToJson(Object object) {
            try {
                if (object != null) {
                    return objectMapper.writeValueAsString(object);
                }
            } catch (JsonProcessingException e) {
                LOG.error("parse {} to json error!", object, e);
            }
            return null;
        }
    
        /**
         * 将JSON对象反序列化成一个Java原生对象, 不支持泛型.
         *
         * @param json JSON对象
         * @param cls  Java对象原始类型的class对象
         * @param <T>  Java对象的原始类型
         * @return 返回一个T类型的对象
         */
        public static <T> T jsonToObj(String json, Class<T> cls) {
            try {
                if (json != null && json.length() > 0) {
                    return objectMapper.readValue(json, cls);
                }
            } catch (IOException e) {
                LOG.error("parse {} to object error!", json, e);
            }
            return null;
        }
    
        /**
         * 将JSON反序列化成一个Java对象, 支持泛型.
         * TypeReference是一个抽象类, 用来构造类型
         * 调用方式: 传入一个TypeReference的匿名实现类即可
         * User user = jsonToObj(json, new TypeReference<User>(){})
         * List<User> users = jsonToObj(json, new TypeReference<List<User>>(){})
         *
         * @param json          JSON对象
         * @param typeReference 类型引用
         * @param <T>           返回值类型
         * @return 返回一个Java对象
         */
        public static <T> T jsonToObj(String json, TypeReference<?> typeReference) {
            try {
                if (json != null && json.length() > 0) {
                    return objectMapper.readValue(json, typeReference);
                }
            } catch (Exception e) {
                LOG.error("parse {} to object error!", json, e);
            }
            return null;
        }
    
        /**
         * 将一个JSON数组反序列化成一个List对象.
         *
         * @param json JSON数组
         * @param cls  Java对象原始类型的class对象
         * @param <T>  Java对象的原始类型
         * @return 返回一个List列表
         */
        public static <T> List<T> jsonToList(String json, Class<T> cls) {
            List<T> list = new ArrayList<>();
            try {
                if (json != null && json.length() > 0) {
                    JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
                    list = objectMapper.readValue(json, javaType);
                }
            } catch (IOException e) {
                LOG.error("parse {} to object error!", json, e);
            }
            return list;
        }
    }
    
    
    
  • 相关阅读:
    什么是序列化
    命令执行漏洞
    sql注入总结
    npm包之merge-descriptors
    Koa路由中间件之koa-router
    TypeScript声明文件(.d.ts)的使用
    TypeScript使用的简单记录
    TypeScript的安装、使用及配置
    Node websocket简单封装
    使用docker-compose配置mysql服务
  • 原文地址:https://www.cnblogs.com/wt20/p/9729481.html
Copyright © 2011-2022 走看看