zoukankan      html  css  js  c++  java
  • 几种序列化与Get、Set方法的关系

    若get开头且第四个字母是大写的方法中有空指针异常时(无论有没有对应属性)

    • 1.阿里巴巴的FastJson会出现空指针异常,证明与get开头的方法有关
    • 2.Google的Gson不会出现异常,因为只和属性有关,和get开头的方法没关系
    • 3.java开源的Jackson也会出现异常,证明与get开头的方法有关

    但是set开头的方法有异常时,三种序列化都不会影响

    下面是三种的maven依赖

    <dependencies>
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.28</version>
      </dependency>
      <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.2.4</version>
      </dependency>
      <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.3.1</version>
      </dependency>
    <dependencies>

    测试代码:

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.gson.Gson;
    
    public class TestFastJson {
        public static void main(String[] args) {
           test();
        }
        public static void test() {
            Student student = new Student();
            student.setName("huyanxia");
            //1.阿里巴巴的FastJson会出现空指针异常
            System.out.println(JSON.toJSON(student));
            //同样会出现空指针异常
            System.out.println(JSONObject.parseObject(JSON.toJSONString(student),student.getClass()));
            //2.Google的Gson不会出现异常,因为只和属性有关,和get开头的方法没关系
            Gson gson = new Gson();
            gson.toJson(student);
            //3.java开源的Jackson也会出现异常,证明与get开头的方法有关
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                objectMapper.writeValueAsString(student);
            }catch(JsonProcessingException e){
                e.printStackTrace();
            }
        }
    }
    class Student{
        private String name;
        private Integer age;
        private String gender;
        private Teacher teacher;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return null;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getGender() {
            return null;
        }
        //没有Num属性,但是getNum方法中有异常,所有get开头的方法序列化时会被调用
        public String getNum(){
            return teacher.getName();
        }
    
        //Num()方法中有异常,但是序列化正常
        public String Num() {
            return teacher.getName();
        }
        //setNum方法没有关系,即使其中有异常,序列化也没有问题
        public void setNum(){
            teacher.getName();
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    }
    class Teacher{
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    JSON.toJSONString方法字符串输出的顺序与对象不一致,可以通过注解解决:

    第一种:通过在实体类添加@JSONType(orders={"name","age","gender","height","weight"})
    @JSONType(orders={"name","age","gender","height","weight"})
    public class Person {
        private String name;
        private Integer age;
        private String gender;
        private Double height;
        private Double weight;
    }
    第二种:在属性上添加@JSONField(ordinal = 1)
    public class Person {
        @JSONField(ordinal = 1)
        private String name;
        @JSONField(ordinal = 2)
        private Integer age;
        @JSONField(ordinal = 3)
        private String gender;
        @JSONField(ordinal = 4)
        private Double height;
        @JSONField(ordinal = 5)
        private Double weight;
    }

    JSON.toJSONString方法序列化时,需要排除一些字段,或者使字段名称缩短,可以使用注解

    //不会序列化   
    @JSONField(serialize = false)
    private ActivitySKUStatusEnum statusEnum;
    //字段名称缩短
    @JSONField(name = "type")
    private PromotionEnum promotionEnum;

    注意:

    org.springframework.beans.BeanInstantiationException异常解决

    在引入阿里巴巴的FastJson的maven依赖时,若项目已经引入spring包,那么需要排除阿里巴巴的spring,如下:

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.3.2</version>
        <exclusions>
           <exclusion>
           <groupId>org.springframework</groupId>
           <artifactId>spring</artifactId>
           </exclusion>
        </exclusions>
    </dependency>

    友情提醒一下:

    由于fastjson低版本存在反序列化漏洞,建议大家用较新版本,至少在1.2.28版本以上吧

  • 相关阅读:
    【原创】主机不能访问虚拟机CentOS7中的站点
    phpStudy中MySQL版本升级到5.7.17方法
    phpStudy for Linux (lnmp+lamp一键安装包)
    Linux的wget命令详解【转载】
    重置密码解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    mysql5.7密码过期ERROR 1862 (HY000): Your password has expired. To log in you must change
    电赛菜鸟营培训(二)——STM32F103CB之中断控制
    电赛菜鸟营培训(零)——Keil环境搭建
    电赛菜鸟营培训(一)——STM32F103CB之LED控制
    AppInventor学习笔记(四)——打地鼠应用学习
  • 原文地址:https://www.cnblogs.com/47Gamer/p/14000029.html
Copyright © 2011-2022 走看看