几种序列化与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版本以上吧

posted @ 2020-11-18 15:20  47号Gamer丶  阅读(920)  评论(0编辑  收藏  举报