fastjson提供了一整套方便将一个对象和json字符串来回转换的工具类,熟练的掌握这个工具不仅可以使我们的代码看起来更加优雅流畅,还能减轻系统的压力。时至今日,json已经成为程序开发中不可或缺的一部分,本文将以alibaba的fastjson为例,根据实际开发需要提供一整套解决方法。

首先,我们先引入开发所需要的jar包依赖,我使用的是1.2.27版本,大家可以根据自己实际开发需要自行引入相应的版本。

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.27</version>
</dependency>

一、json与对象互转

先新建个Student对象

public class Student {

    //姓名
    private String name;

    //年龄
    private String age;

    //性别
    private String sex;
    
    //地址
    private String address;

    //生日
    private Date birthday;
}

1.1、对象转json

Student stu = new Student();
stu.setName("张三");
stu.setSex("男");
stu.setAge("18");
stu.setAddress("浙江");
stu.setBirthday(new Date());
//对象转json
String json = JSON.toJSONString(stu);

1.2、json转对象

//json转Student对象
Student student = JSON.parseObject(json, Student.class);

1.3、对象与json互转时常用方法

1.3.1、@JSONField

        在对象与json互转过程中经常会有某些特殊的需求,比如不想要某些属性,改变某些属性的值或者其他逻辑。

public class Student {

    //姓名
	@JSONField(name="NAME", serialize=false)
	//JSONField是fastjson下的一个注解,name:指定序列化后的属性值为NAME,
	//serialize:默认为true,false为不序列化该属性
    private String name;

    //年龄
	@JSONField(name="AGE", deserialize=false)
	//deserialize:默认为true,false为不反序列化该属性
    private String age;

    //性别
	@JSONField(name="SEX", ordinal=1)
	//ordinal:指定SEX属性的顺序为1
    private String sex;
    
    //地址
	@JSONField(name="ADDRESS", ordinal=2)
	//ordinal:指定ADDRESS属性的顺序为2
    private String address;

    //生日
	@JSONField(name="BIRTHDAY", format="dd/MM/yyyy", ordinal = 3)
	//ordinal:指定BIRTHDAY属性的顺序为3
	//format:只能用于Date类型,格式化Date属性
    private Date birthday;
}

1.3.2、ContextValueFilter


        ContextValueFilter是fastjson提供的接口,在操作时可以创建新的实现类去操作需要获得所属JavaBean的信息,包括类型、字段、方法等,并且对上下文进行相关的逻辑操作。


Student stu = new Student();
stu.setName("张三");
stu.setSex("男");
stu.setAge("18");
stu.setAddress("浙江");
stu.setBirthday(new Date());
ContextValueFilter filter = new ContextValueFilter() {
	@Override
	public Object process(BeanContext beanContext, Object o, String s, Object o1) {
        //将key为AGE的值改成小写
		if (StringUtils.equals(s, "AGE")) {
			return s.toUpperCase();
		}
        //将SEX对应的值改成false
		(StringUtils.equals(s, "SEX")) {
			return false;
		}
        //如果value值为String,拼接上filter
		if (o1 instanceof String) {
			String key = (String) o1;
			return key + "filter";
		}
		return null;
	}
};
String json = JSON.toJSONString(stu, filter);
//json ==> {"SEX":false,"AGE":"age","ADDRESS":"浙江filter"}
System.out.println(json);

二、json与List互转

2.1、list里面为string

list转json:

List<String> strings = new ArrayList<>();
strings.add("aa");
strings.add("bb");
strings.add("cc");
String stringJson = JSON.toJSONString(strings);
//stringJson ==> ["aa","bb","cc"]
System.out.println(stringJson);

json转list

List<String> list = JSON.parseArray(stringJson, String.class);

2.2、list里面为对象

List<Student> studentList = new ArrayList<>();
Student stu = new Student();
stu.setName("张三");
stu.setSex("男");
stu.setAge("18");
stu.setAddress("浙江");
stu.setBirthday(new Date());
studentList.add(stu);
String stuJson = JSON.toJSONString(studentList);
//stuJson ==> [{"SEX":"男","AGE":"18","ADDRESS":"浙江","BIRTHDAY":"04/01/2022"}]
System.out.println(stuJson);
List<Student> students = JSON.parseArray(stuJson, Student.class);

三、map与json互转

map转json

Map<String,String> map = new HashMap<>();
map.put("a","aa");
map.put("b","bb");
map.put("c","cc");
String mapJson = JSON.toJSONString(map);
//mapJson ==> {"a":"aa","b":"bb","c":"cc"}
System.out.println(mapJson);

json转map

Map<String,String> originMap = JSON.parseObject(mapJson, Map.class);
String a = originMap.get("a");
System.out.println(a);

四、JSONObject与json

        JSONObject是fastjson提供的一个对象,本质上是实现了Map<String, Object>,并且继承了JSON。可以这样理解,json格式的string对象是一个Map<String, Object>,我们在使用JSON.parseObject()进行转换的时候没有指定键值对中value的类型,所以用Object填充,因此获得的结果就是JSONObject,如果指定了对象那么返回值就是我们指定的对象。

JSONObject转json

JSONObject jsonObject = new JSONObject();
jsonObject.put("a","aa");
String jsonString = jsonObject.toJSONString();
//jsonString ==> {"a":"aa"}
System.out.println(jsonString);

json转JSONObject

JSONObject originJsonObject = JSON.parseObject(jsonString);
String a = (String) originJsonObject.get("a");
//a ==> aa
System.out.println(a);

五、TypeReference

        TypeReference也是fastjson提供的一个对象,这个对象的目的是指定反序列化时的对象类型

Map<String, Map<String, List<Student>>> map = new HashMap<>();
Map<String, List<Student>> innerMap = new HashMap<>();
List<Student> studentList = new ArrayList<>();
Student stu = new Student();
stu.setName("张三");
stu.setSex("男");
stu.setAge("18");
stu.setAddress("浙江");
stu.setBirthday(new Date());
studentList.add(stu);
innerMap.put("studentList", studentList);
map.put("innerMap", innerMap);
String mapJson = JSON.toJSONString(map);
//mapJson ==> {"innerMap":{"studentList":[{"SEX":"男","AGE":"18","ADDRESS":"浙江","BIRTHDAY":"04/01/2022"}]}}
System.out.println(mapJson);
Map<String, Map<String, List<Student>>> origin = JSON.parseObject(mapJson, new TypeReference<Map<String, Map<String, List<Student>>>>(){});
System.out.println(origin);

六、总结

        根据java的一切皆对象来说,不管是String、List、Map还是对象都是对象,因此转成json的string都可以使用JSON.toJSONString(obj)

/**
 * json格式化
 * @param obj
 * @return
 */
public static String toJsonString(Object obj) {
	return JSON.toJSONString(obj);
}

        而将json的string转化成对象,根据其本质(json的string本质可以理解成Map<String, Object>)可以分成两种,一种是对象(包括Map、String、Object等),一种是list(list本身也是对象)

/**
     * 解析json
     *
     * @param json
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T parseObject(String json, Class<T> clazz) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        Assert.notNull(clazz);
        return JSON.parseObject(json, clazz);
    }

    /**
     * 解析json数组
     * @param json
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> parseArray(String json, Class<T> clazz) {
        if (StringUtils.isBlank(json)) {
            return Collections.emptyList();
        }
        Assert.notNull(clazz);
        return JSON.parseArray(json, clazz);
    }

        因此在json的string转化成对象时尽可能的使用对象接收,如果不用对象接收也要尽可能的使用TypeReference指定转换后的类型。