zoukankan      html  css  js  c++  java
  • SpingBoot序列化以及反序列化

    一、Java常见的序列化与饭序列化工具

    1、jackson(springboot默认的序列化工具),jackson底层采用的是ObjectMapper技术进行序列化以及反序列化的。

    2、alibaba-fastjson。

    二、SpringBoot日期格式序列化(特定讲一下)

    1、SpringBoot默认是可以接受时间戳格式自动转换成java.util.Date。默认是不支持字符串自动转成java.util.Data。

    2、SpringBoot如何接收字符串自动转换成java.util.Date

    2.1 全局处理方式 (配置文件)。

    #Spring默认接收时间戳进行反序列化到Date。这样就可以同时支持时间戳或者自定义的字符串格式日期转java.util.Date
    spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
    #jackson默认的时区是Greenwich Time,我们所处的是东八区
    spring.jackson.time-zone=GMT+8

    接受请求

     输出格式

    2.2 具体字段具体处理方式

    @JsonFormat这里会覆盖前面配置文件的格式 用于application/json的时候

     

    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") 用于表单multipart/form-data提交的方式

    public class DataDTO {
    
        private String name;
    
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") //用于application/json  可以决定序列化以及发序列化的格式
        //@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") //用于multipart/form-data表单提交方式 只能决定反序列化的格式
        private Date create;
    
        private Integer count;
    
        private String cA;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Date getCreate() {
            return create;
        }
    
        public void setCreate(Date create) {
            this.create = create;
        }
    
        public Integer getCount() {
            return count;
        }
    
        public void setCount(Integer count) {
            this.count = count;
        }
    
        public String getcA() {
            return cA;
        }
    
        public void setcA(String cA) {
            this.cA = cA;
        }
    }

    三、SpringBoot默认jackson序列化工具常用注解

    1、序列化以及反序列化都会生效注解

    1.1、@JsonIgnoreProperties(value = {"name"},ignoreUnknown = true)

     下列演示一下ignoreUnknown = true的作用

    @JsonIgnoreProperties(value = {"name"},ignoreUnknown = true)
    public class DataDTO { private String name; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date create; private Integer count; private String cA;
    ......set get......
    }
        public static void main(String[] args) throws JsonProcessingException {
            String json = "{
    " +
                    "    "name": "testName",
    " +
                    "    "create": "2021-07-02 08:46:53",
    " +
                    "    "count": 6,
    " +
                    "    "cA": "testCA",
    " +
                    "    "cB": "testCA"
    " +
                    "}";
            ObjectMapper mapper = new ObjectMapper();
            DataDTO dataDTO = mapper.readValue(json, DataDTO.class);
            System.out.println(dataDTO);
        }

    如上代码如果不加ignoreUnknown=true则会出现以下异常,但是经过实际测试多字段会出现一下异常,少字段不会出现以下异常。

     1.2、@JsonProperty("name")

     用在属性上以及GET/SET方法上,如果用在属性上那么GET/SET都将已属性上的name为准。

    如果用在GET/SET上则,各自用各自的name处理,至于未找的属性值则为null处理。

     

     另外@JsonProperty直接注释在属性上的话,没有GET/SET都会被序列化的。但是alibab fast json序列化需要GET/SET方法。

    @JsonProperty会强制private变成public,所以将会以注解的实际名称处理。

    /*
    * 情况一
    */
    @JsonProperty("cA") private String cA; public String getCA(){ return cA; } public void setCA(String cA){ this.cA = cA; }

    /*
    * 情况二
    */

    public String cA;
    
    public String getCA(){
       return cA;
    }
    
    public void setCA(String cA){
      this.cA = cA;
    }
     

    以上两种情况都会出现下面这种情况

     由上可以推测SpringBoot在对象的序列化以及反序列化的时候,是已GET/SET后面的字符串决定的。如果是public属性则会出现GET以及属性本身的名称值。如果是private属性则只会序列化GET标准的名称。

    属性本身的值以及GET方法解析出来的属性值会存放在HashMap当中。对于private的则不会序列化出来,这也就是为什么会出现上面的情况。如果是标准的GET饿会和属性本身名称重名,而且属性本身是private也会移除。public则会重名HashMap中只会保留GET解析出来的名称属性。

    特殊情况命名方式为xAxx方式,例如aA则会出现getAA然后解析出来aa属性,所以会出现aa,aA两个属性。

    jackson2对pojo类型序列化的处理。
    Jackson2在初始化序列器时,对pojo类型对象会收集其属性信息,属性包括成员变量及方法,然后属性名称和处理过后的方法名称做为key保存到一个LinkedHashMap中。
    收集过程中会调用com.fasterxml.jackson.databind.util.BeanUtil中的legacyManglePropertyName方法用来处理方法名称,它会将get
    /set方法前缀,即get或set去掉,并将其后面的连续大写字符转换成小写字符返回。
    例如: getNEWString会转变成newstring返回。你的属性名称如果有这样的"nSmallSellCount",lombok自动生成的get方法就会是这样的"getNSmallSellCount",处理过后就是这样的"nsmallSellCount",这与属性nSmallSellCount并不冲突,
    可以同时存在于HashMap中。收集完属性信息后,下面的步骤中会删除掉非可见的属性,一般指的是私有成员变量,这时,名称为"nSmallSellCount"的成员变量属性会被删除掉,这样的序列化结果是不会有问题的,但,如果加了@JsonProperty注释,
    Jackson2会认为这个属性是可见的,不必会删除,这时这两个表示同一个值得属性就会被一同序列化。

     所以在使用lombok的时候出现aAbbb或者aABBb类似的情况要注意。

    @Data
    public class LombokDTO {
        private String aAbbb;
        private String aABBb;
    }


    其实实际aAbbb但是按照lombok应该序列化的是aabbb而不是aAbbb;

     

    所以大家在用lombok的时候要注意,不要被假象所迷惑以实际测试为准。另外发现lombok使用@Builder和@Data的时候默认会没有空构造函数的。需要空构造函数不需同时加上以下注解

    @Data
    @Builder
    @NoArgsConstructor //提供默认无参构造函数
    public class LombokDTO {
    
        private String aAbbb;
    
        public static void main(String[] args) {
               new LombokDTO();
        }
    }

     更多应用可以参考博主:https://www.cnblogs.com/klhans/p/12583751.html

     

     

  • 相关阅读:
    一个分页的存储过程
    自己动手:修改crx文件制作自己的Chrome Apps
    SQLSERVER 过滤所有权的代码
    在ASP.NET中实现多文件上传
    引用 TimeSpan简介
    xml
    常用的正则表达式小结
    ASP.NET事务处理
    创建可在网页下载安装的ActiveX控件(通过Setup.exe安装)
    ASP.NET验证控件应用实例与详解
  • 原文地址:https://www.cnblogs.com/dszazhy/p/14963648.html
Copyright © 2011-2022 走看看