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