FastJson 2『使用心得』

〖FastJson 2〗

『Enum』

FastJson 中的枚举类说明,主要用在序列化和反序列化的API。

﹝JSONWriter.Feature﹞

serializeFeatures 的属性 JSONWriter.Feature。

序号属性作用
1FieldBased基于字段反序列化,如果不配置默认基于 public 的 field 和 getter 方法序列化。
2IgnoreNoneSerializable忽略没有标记 @JSONField(serialize = false) 的字段。
3ErrorOnNoneSerializable当遇到没有标记 @JSONField(serialize = false) 的字段时抛出异常。
4BeanToArray将 JavaBean 序列化为数组而不是对象。
5WriteNulls写入值为 null 的属性。
6BrowserCompatible产生兼容浏览器的 JSON,首字母小写,不带引号。
7NullAsDefaultValue将 null 值作为默认值写入 JSON。
8WriteBooleanAsNumber将布尔类型(Boolean)序列化为 0 或 1 而不是 true/false。
9WriteNonStringValueAsString将非字符串类型写为字符串类型。
10WriteClassName在序列化时写入对象的类名。
11NotWriteRootClassName不写入顶层对象的类名。
12NotWriteHashMapArrayListClassName不写入 HashMap 和 ArrayList 的类名。
13NotWriteDefaultValue不写入默认值。
14WriteEnumsUsingName将枚举类型序列化为名称而不是值。
15WriteEnumUsingToString将枚举类型序列化为 toString() 方法的返回值。
16IgnoreErrorGetter忽略 getter 方法抛出的异常。
17PrettyFormat以漂亮的格式输出 JSON。
18ReferenceDetection启用引用检测。
19WriteNameAsSymbol写入属性的名称作为符号。
20WriteBigDecimalAsPlain将 BigDecimal 序列化为数字而不是字符串。
21UseSingleQuotes使用单引号而不是双引号。
22MapSortField对 Map 类型按照字段名排序。
23WriteNullListAsEmpty将 null 值的 List 类型属性序列化为空数组。
24WriteNullStringAsEmpty将 null 值的 String 类型属性序列化为 “”。
25WriteNullNumberAsZero将 null 值的 Number 类型属性序列化为 0。
26WriteNullBooleanAsFalse将 null 值的 Boolean 类型属性序列化为 false。
27NotWriteEmptyArray不写入空的数组。
28WriteNonStringKeyAsString将非字符串类型的键序列化为字符串。
29WritePairAsJavaBean将键值对序列化为 JavaBean。
30OptimizedForAscii针对 ASCII 字符优化序列化性能。
31EscapeNoneAscii对于超出 ASCII 范围【即代码点为 128 及以上】的字符使用特定的机制输出。
32WriteByteArrayAsBase64以 Base64 编码形式序列化 byte 数组。
33IgnoreNonFieldGetter忽略 getter 方法标记为 @JSONField(serialize = false) 的字段。

﹝JSONReader.Feature﹞

deserializeFeatures的属性 JSONReader.Feature

序号属性作用
1FieldBased使用基于字段的解析方式。
2IgnoreNoneSerializable忽略没有标记 @JSONField(deserialize = false) 的非反序列化字段。
3ErrorOnNoneSerializable遇到没有标记 @JSONField(deserialize = false) 的字段时抛出异常。
4SupportArrayToBean支持将数组转换为 JavaBean 对象。
5InitStringFieldAsEmpty将字符串类型的属性初始化为空字符串。
6SupportAutoType支持自动类型转换。
7SupportSmartMatch支持智能匹配。
8UseNativeObject使用本地对象进行解析。
9SupportClassForName支持使用类名进行解析。
10IgnoreSetNullValue忽略设置为 null 的属性值。
11UseDefaultConstructorAsPossible尽量使用默认构造函数进行实例化。
12UseBigDecimalForFloats使用 BigDecimal 解析浮点数。
13UseBigDecimalForDoubles使用 BigDecimal 解析双精度浮点数。
14ErrorOnEnumNotMatch当枚举类型不匹配时抛出异常。
15TrimString修剪字符串的前导和尾随空格。
16ErrorOnNotSupportAutoType当不支持自动类型转换时抛出异常。
17DuplicateKeyValueAsArray将重复的键值对解析为数组。
18AllowUnQuotedFieldNames允许不使用引号的字段名。
19NonStringKeyAsString将非字符串类型的键解析为字符串。
20Base64StringAsByteArray将 Base64 编码的字符串解析为字节数组。

﹝PropertyNamingStrategy﹞

使用NameFilter.of 方法时需要传枚举类,以下是枚举类的说明。

序号属性作用
1CamelCase『序列化』保持原样。
2PascalCase『序列化』首字母大写。
3SnakeCase『序列化』使用下划线分隔单词,且全部小写。
4UpperCase『序列化』全部大写。
5UpperCamelCaseWithSpaces『序列化』首字母大写,单词之间用空格分隔。
6UpperCamelCaseWithUnderScores『序列化』首字母大写,单词之间用下划线分隔。
7UpperCamelCaseWithDashes『序列化』首字母大写,单词之间用破折号分隔。
8UpperCamelCaseWithDots『序列化』首字母大写,单词之间用点号分隔。
9KebabCase『序列化』全部小写,单词之间用破折号分隔。
10UpperCaseWithUnderScores『序列化』全部大写,单词之间用下划线分隔。
11UpperCaseWithDashes『序列化』全部大写,单词之间用破折号分隔。
12UpperCaseWithDots『序列化』全部大写,单词之间用点号分隔。
13LowerCase『序列化』全部小写。
14LowerCaseWithUnderScores『序列化』全部小写,单词之间用下划线分隔。
15LowerCaseWithDashes『序列化』全部小写,单词之间用破折号分隔。
16LowerCaseWithDots『序列化』全部小写,单词之间用点号分隔。

『JavaBean』

包括后面可能会用到一些实体类、实现类、接口、注解,等。可以暂时跳过,后面用到的时候再拿过来看。

﹝Annotate﹞

package com.ruoyi.project.missionnel.annotate;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface Alias {
    String value() default "";
    Name[] names() default {};
}
package com.ruoyi.project.missionnel.annotate;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface Name {

    String type();

    String value();

}

﹝Bean﹞

package com.ruoyi.project.missionnel.bean;

import com.ruoyi.project.missionnel.inter.JavaBean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Family implements JavaBean {

    private String father = "阿柴的爸爸";

    private String mother = "阿柴的妈妈";

    private String brother = "阿柴的哥哥";

    private String sister = "阿柴的姐姐";

}
package com.ruoyi.project.missionnel.bean;

import com.ruoyi.project.missionnel.annotate.Alias;
import com.ruoyi.project.missionnel.annotate.Name;
import com.ruoyi.project.missionnel.inter.JavaBean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message implements JavaBean {

    @Alias(names = {@Name(type = "Small", value = "message"), @Name(type = "Big", value = "MESSAGE")})
    private String msg;
    
}
package com.ruoyi.project.missionnel.bean;

import com.ruoyi.project.missionnel.inter.JavaBean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Params<T> implements JavaBean {
    private T param;
}
package com.ruoyi.project.missionnel.bean;

import com.alibaba.fastjson2.annotation.JSONField;
import com.ruoyi.project.missionnel.inter.JavaBean;
import com.ruoyi.project.missionnel.support.JsonParser;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

import static com.alibaba.fastjson2.JSONReader.Feature.InitStringFieldAsEmpty;
import static com.alibaba.fastjson2.JSONWriter.Feature.NotWriteDefaultValue;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Student implements JavaBean {

    private static final long serialVersionUID = -3289647584974663707L;

    @JSONField(name = "userName", label = "ELS", alternateNames = {"myName", "testName"})
    private String name;

    @JSONField(ordinal = 1)
    private Integer age;

    @JSONField(ordinal = 2)
    private String gender;

    @JSONField(defaultValue = "开朗")
    private String character;

    @JSONField(serialize = false)
    private String job;

    @JSONField(deserialize = false)
    private String address;

    @JSONField(serializeFeatures = {NotWriteDefaultValue})
    private String father;

    @JSONField(deserializeFeatures = {InitStringFieldAsEmpty})
    private String mother;

    @JSONField(format = "yyyy年MM月dd日 HH时mm分ss秒")
    private Date birthday;

    @JSONField(deserializeUsing = JsonParser.class)
    private String sister;

    @JSONField(serializeUsing = JsonParser.class)
    private String brother;

    @JSONField(jsonDirect = true)
    private String json;

    @JSONField(unwrapped = true)
    private Message message;

}
package com.ruoyi.project.missionnel.bean;

import com.alibaba.fastjson2.annotation.JSONField;
import com.ruoyi.project.missionnel.inter.JavaBean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements JavaBean {

    @JSONField(name = "哈哈哈")
    private String name = "阿柴";

    private int age = 18;

    private String sex = "男";

    private long height = 180;

    private long weight = 150;

    private Family family = new Family();

}

﹝Filter﹞

package com.ruoyi.project.missionnel.filter;

import com.alibaba.fastjson2.filter.NameFilter;
import com.ruoyi.project.missionnel.annotate.Alias;
import com.ruoyi.project.missionnel.annotate.Name;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AliasFilter implements NameFilter {

    private String type;

    @Override
    public String process(Object javaType, String key, Object value) {
        try {

            Alias alias = javaType.getClass().getDeclaredField(key).getDeclaredAnnotation(Alias.class);

            Name[] names = alias.names();

            String defaultName = alias.value();

            if (names.length == 0 && defaultName.length() > 0) return defaultName;

            for (Name name : names) if (type.equals(name.type())) return name.value();

        } catch (Exception e) {

            return key;

        }

        return key;
    }
}

﹝Interface﹞

package com.ruoyi.project.missionnel.inter;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

public interface JavaBean {

    /**
     * 将JavaBean转化成JSONString
     * @return
     */
    default String toJSONString() {
        return JSON.toJSONString(this);
    }

    /**
     * 将JavaBean转化成JSONObject
     * @return
     */
    default JSONObject toJSONObject() {
        return (JSONObject) JSON.toJSON(this);
    }

}

﹝Support﹞

package com.ruoyi.project.missionnel.support;

import cn.hutool.core.lang.Console;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.writer.ObjectWriter;

import java.lang.reflect.Type;

@SuppressWarnings("rawtypes")
public class JsonParser implements ObjectReader, ObjectWriter {

    @Override
    public long getFeatures() {
        return ObjectReader.super.getFeatures();
    }

    @Override
    public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
        String str = jsonReader.readString();
        Console.error("Read测试文字: {}", str);
        return str;
    }


    @Override
    public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
        Console.error("Write测试文字: {}", object.toString());
        jsonWriter.writeString(object.toString());
    }
}

『JSON』

JSON 接口定义了类型转换的API。包括 Object 类转换成 String 【序列化】,和 String 转换成 Object 类【反序列化】。同时重载了很多方法,用来自定义序列化和反序列化。因为是接口,所以里面定义的方法都是 Static 的,可以直接调用。

﹝JSON.toJSONString﹞

可以把 Object 类型的对象进行序列化,同时有很多重载方法,可以通过 JSONWriter.Feature 自定义序列化行为。

        User user = new User();

        //第一种使用方法
        String jsonString1 = JSON.toJSONString(user);

        //第二种使用方法,属性PrettyFormat会美化输出。
        String jsonString2 = JSON.toJSONString(user, JSONWriter.Feature.PrettyFormat);

        //第三种使用方法,这里我们实现了一个过滤器接口,这个接口的实现详情在后面会说明,这里我们只作展示。
        String jsonString3 = JSON.toJSONString(user, new AliasFilter());

        System.out.println(jsonString1);
        System.out.println(jsonString2);
        System.out.println(jsonString3);

        /*
        {"age":18,"family":{"brother":"阿柴的哥哥","father":"阿柴的爸爸","mother":"阿柴的妈妈","sister":"阿柴的姐姐"},"height":180,"sex":"男","weight":150,"哈哈哈":"阿柴"}
        {
            "age":18,
                "family":{
            "brother":"阿柴的哥哥",
                    "father":"阿柴的爸爸",
                    "mother":"阿柴的妈妈",
                    "sister":"阿柴的姐姐"
        },
            "height":180,
                "sex":"男",
                "weight":150,
                "哈哈哈":"阿柴"
        }
        {"age":18,"family":{"brother":"阿柴的哥哥","father":"阿柴的爸爸","mother":"阿柴的妈妈","sister":"阿柴的姐姐"},"height":180,"sex":"男","weight":150,"哈哈哈":"阿柴"}
        */

﹝JSON.parse﹞

将字符串反序列化成对象,返回的对象是 Object ,也就意味着可以强转换成 JSONObject 或者是 JSONArray。这个方法还有多个重载方法,可以通过 JSONWriter.Feature 来进行反序列化。

        String str = "{\"age\":18,\"family\":{\"brother\":\"阿柴的哥哥\",\"father\":\"阿柴的爸爸\",\"mother\":\"阿柴的妈妈\",\"sister\":\"阿柴的姐姐\"},\"height\":180,\"sex\":\"男\",\"weight\":150,\"哈哈哈\":\"阿柴\"}";

        Object parse = JSON.parse(str);

        System.out.println(parse);

		//{"age":18,"family":{"brother":"阿柴的哥哥","father":"阿柴的爸爸","mother":"阿柴的妈妈","sister":"阿柴的姐姐"},"height":180,"sex":"男","weight":150,"哈哈哈":"阿柴"}

﹝JSON.parseObject﹞

另一种反序列化方式,这种方式处理的方式更加丰富。可以把字符串反序列化成 JSONObject 或者 Java 实体类,如果是携带泛型的实体类,可以用 TypeReference 进行处理。

        String str = "{\"age\":18,\"family\":{\"brother\":\"阿柴的哥哥\",\"father\":\"阿柴的爸爸\",\"mother\":\"阿柴的妈妈\",\"sister\":\"阿柴的姐姐\"},\"height\":180,\"sex\":\"男\",\"weight\":150,\"哈哈哈\":\"阿柴\"}";
        String string = "{\"param\":\"泛型参数\"}";

        JSONObject jsonObject = JSON.parseObject(str);

        User user = JSON.parseObject(str, User.class);

        Params<String> params = JSON.parseObject(string, new TypeReference<Params<String>>() {});

        System.out.println(jsonObject);
        System.out.println(user);
        System.out.println(params);

		//{"age":18,"family":{"brother":"阿柴的哥哥","father":"阿柴的爸爸","mother":"阿柴的妈妈","sister":"阿柴的姐姐"},"height":180,"sex":"男","weight":150,"哈哈哈":"阿柴"}
		//User(name=阿柴, age=18, sex=男, height=180, weight=150, family=Family(father=阿柴的爸爸, mother=阿柴的妈妈, brother=阿柴的哥哥, sister=阿柴的姐姐))
		//Params(param=泛型参数)

﹝JSON.to﹞

本身是一个万能的转换 API ,但是如果是实体类,转换成 JSONObject 就会抛出异常。但是其他的的 API 会弥补这个不足。

        User user = new User();

        String str = JSON.to(String.class, user);

        JSONObject jsonObject = JSON.to(JSONObject.class, str);

        User userNew = JSON.to(User.class, str);

        //会抛出异常,看了下源码,没有匹配到相应的序列化方式。感觉是FastJson的一个漏洞。不过也不能算是漏洞,因为其他的API可以弥补这个情况。
        //JSONObject user4 = JSON.to(JSONObject.class, user);

        System.out.println(str);
        System.out.println(jsonObject);
        System.out.println(userNew);

		//{"age":18,"family":{"brother":"阿柴的哥哥","father":"阿柴的爸爸","mother":"阿柴的妈妈","sister":"阿柴的姐姐"},"height":180,"sex":"男","weight":150,"哈哈哈":"阿柴"}
		//{"age":18,"family":{"brother":"阿柴的哥哥","father":"阿柴的爸爸","mother":"阿柴的妈妈","sister":"阿柴的姐姐"},"height":180,"sex":"男","weight":150,"哈哈哈":"阿柴"}
		//User(name=阿柴, age=18, sex=男, height=180, weight=150, family=Family(father=阿柴的爸爸, mother=阿柴的妈妈, brother=阿柴的哥哥, sister=阿柴的姐姐))

﹝JSON.toJSON﹞

可以将实体类转换成 JSONObject 或者 JSONArray 。但是返回值是 Object 所以需要强转。但是 String 类型的字符串不能转换,会抛出异常。

		String[] array = {"1", "2", "3"};        
		User user = new User();

        JSONObject json = (JSONObject) JSON.toJSON(user);
        
        JSONArray jsonArray = (JSONArray) JSON.toJSON(array);

		System.out.println(json);
        System.out.println(jsonArray);

		//{"age":18,"family":{"brother":"阿柴的哥哥","father":"阿柴的爸爸","mother":"阿柴的妈妈","sister":"阿柴的姐姐"},"height":180,"sex":"男","weight":150,"哈哈哈":"阿柴"}
		//["1","2","3"]

『JSONObject』

﹝Put 及其衍生﹞

put:放入键值对。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        //{"name":"阿柴"}

fluentPut:和 put 的作用是一样的,但是可以实现链式编程。

        JSONObject json = new JSONObject().fluentPut("name", "阿柴").fluentPut("age", 18).fluentPut("sex", "男").fluentPut("address", "北京市中南海");
        //{"name":"阿柴","age":18,"sex":"男","address":"北京市中南海"}

putIfAbsent: 将键值对放入 JSONObject 对象,如果放入的Key不存在,将键值对放入,如果Key存在,那么不做替换处理,返回当前Key对应的值。

        JSONObject json = new JSONObject().fluentPut("name", "阿柴").fluentPut("age", 18).fluentPut("sex", "男").fluentPut("address", "北京市中南海");

        Object resultName = json.putIfAbsent("name", "黑柴");
        Object resultGirlFriend = json.putIfAbsent("girlFriend", "白柴");

        System.out.println(json);
        System.out.println(resultName);
        System.out.println(resultGirlFriend);

        //{"name":"阿柴","age":18,"sex":"男","address":"北京市中南海","girlFriend":"白柴"}
        //阿柴
        //null

putAll:将 Map<? extends K, ? extends V> 类型的参数,放入 JSONObject 对象中。JSONObject 继承了 LinkedHashMap 所以也可以传入。

        JSONObject json = new JSONObject().fluentPut("name", "阿柴").fluentPut("age", 18);

        JSONObject jsonAnother = new JSONObject().fluentPut("sex", "男").fluentPut("address", "北京市中南海");
        jsonAnother.putAll(json);

        System.out.println(json);
        System.out.println(jsonAnother);

        //{"name":"阿柴","age":18}
        //{"sex":"男","address":"北京市中南海","name":"阿柴","age":18}

构造函数:构造函数可以将 Map 类型的对象初始化。

        JSONObject json = new JSONObject().fluentPut("name", "阿柴").fluentPut("age", 18);

        JSONObject jsonAnother = new JSONObject(json).fluentPut("sex", "男").fluentPut("address", "北京市中南海");

        System.out.println(json);
        System.out.println(jsonAnother);

        //{"name":"阿柴","age":18}
        //{"name":"阿柴","age":18,"sex":"男","address":"北京市中南海"}

﹝Get 及其衍生 💗﹞

get:get可以获取 JSONObject 中存入的值,get有很多衍生的方法。例如 getString 可以直接把获取的值,转换为 String 而不需要手动强转,这一点既安全又方便;其他类型的参数也有相关的API

例如:getDouble、getFloat、getLong、getShort、getByte、getBoolean、getBigInteger、getBigDecimal、getDate、getInstant,这里不再进行展示。

        JSONObject json = new JSONObject();

        JSONObject address = new JSONObject();
        address.put("country", "中国");
        address.put("province", "天津市");
        address.put("city", "天津市");
        address.put("area", "河西区");

        JSONArray cars = new JSONArray();
        cars.add("保时捷918");
        cars.add("法拉利拉法");
        cars.add("迈凯伦P1");

        List<String> girlFriends = new ArrayList<>();
        girlFriends.add("桃乃木奈香");
        girlFriends.add("枫花恋");
        girlFriends.add("水野朝阳");
        girlFriends.add("筱田优");
        girlFriends.add("美乃雀");
        girlFriends.add("三上悠亚");
        girlFriends.add("葵司");
        girlFriends.add("深田咏美");

        Family family = new Family();

        Params<String> params = new Params<>();
        params.setParam("泛型参数");

        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("nation", "汉族");
        json.put("address", address);
        json.put("girlFriends", girlFriends);
        json.put("cars", cars);
        json.put("family", family);
        json.put("params", params);

        Object name = json.get("name");
        int age = json.getIntValue("age");
        String sex = json.getString("sex");

        // getOrDefault:该方法只判断是否为null,只有值为null的时候返回默认值,如果数据为空串"",是不会返回默认值的。
        Object nation = json.getOrDefault("nation", "没有数据!");
        Object idCard = json.getOrDefault("idCard", "没有数据!");

        JSONObject addressJson = json.getJSONObject("address");
        JSONArray carsJson = json.getJSONArray("cars");
        List<String> girls = json.getList("girlFriends", String.class);
        Family familyObj = json.getObject("family", Family.class);

        //如果JavaBean中携带泛型,需要使用TypeReference类来进行处理。
        Params<String> paramsStr = json.getObject("params", new TypeReference<Params<String>>() {});

        //或者可以使用另一种形式,但是这种形式不推荐,意义不大。
        TypeReference<Params<String>> typeReference = new TypeReference<Params<String>>() {};
        Type type = typeReference.getType();
        Params<String> paramsType = json.getObject("params", type);

        System.out.println(name);
        System.out.println(age);
        System.out.println(sex);
        System.out.println(nation);
        System.out.println(idCard);
        System.out.println(addressJson);
        System.out.println(carsJson);
        System.out.println(girls);
        System.out.println(familyObj);
        System.out.println(paramsStr);
        System.out.println(paramsType);

		//阿柴
		//18
		//男
		//汉族
		//没有数据!
		//{"country":"中国","province":"天津市","city":"天津市","area":"河西区"}
		//["保时捷918","法拉利拉法","迈凯伦P1"]
		//[桃乃木奈香, 枫花恋, 水野朝阳, 筱田优, 美乃雀, 三上悠亚, 葵司, 深田咏美]
		//Family(father=阿柴的爸爸, mother=阿柴的妈妈, brother=阿柴的哥哥, sister=阿柴的姐姐)
		//Params(param=泛型参数)
		//Params(param=泛型参数)

﹝containsKey﹞

containsKey:判断当前对象存在已有的Key。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", "18");
        json.put("sex", "男");

        boolean name = json.containsKey("name");
        System.out.println(name);

		//true

﹝containsValue﹞

containsValue:当前对象是存在已有Value。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", "18");
        json.put("sex", "男");

        boolean name = json.containsValue("阿柴");
        System.out.println(name);

﹝nameFilter﹞

nameFilter:将Key的值进行统一变动,我们这里添加前缀和后缀。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", "18");
        json.put("sex", "男");

        //这是名字过滤器,详细用法在后面有介绍。这里知道有这个API即可。
        NameFilter nameFilter = (Object object, String name, Object value) -> "pre_" + name + "_suf";
        json.nameFilter(nameFilter);

		System.out.println(json);
		
		//{"pre_name_suf":"阿柴","pre_age_suf":"18","pre_sex_suf":"男"}

﹝valueFilter﹞

valueFilter:和 nameFilter 一样,统一对值进行处理。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        ValueFilter valueFilter = (Object object, String name, Object value) -> "A" + value + "B";
        json.valueFilter(valueFilter);

        System.out.println(json);

		//{"name":"A阿柴B","age":"A18B","sex":"A男B","address":"A北京市B"}

﹝eval﹞

eval:可以用来查找某个值,详细用法可以看后面的JSONPath用法,这里我们知道有这个API即可。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", "18");
        json.put("sex", "男");

        // 详细用法需要看JSONPath,这里我们知道有这个API即可。
        Object eval = json.eval(JSONPath.of("$.sex"));
        System.out.println(eval);

		//男

﹝to 💗﹞

to:把 JSONObject 对象转换成任意 Java 对象。

        JSONObject json = new JSONObject();
        json.put("msg", "阿柴该还京东白条了。");
        json.put("param", "阿柴该还花呗了。");

        //最简单常用的方式
        Message message = json.to(Message.class);

        //如果是使用泛型的类,那么需要TypeReference进行处理。
        Params<String> params = json.to(new TypeReference<Params<String>>() {});

        //泛型的另一种处理方式。
        TypeReference<Params<String>> typeReference = new TypeReference<Params<String>>() {};
        Type type = typeReference.getType();
        Params<String> paramsAnother = json.to(type);

        //通过拉姆达表达式设置函数,处理后返回任意对象,可以返回JavaBean对象,我们这里返回String是想表明可以返回任意对象。
        String lambda = json.to(item -> item.getString("msg"));

        System.out.println(message);
        System.out.println(params);
        System.out.println(paramsAnother);
        System.out.println(lambda);
		
		//Message(msg=阿柴该还京东白条了。)
		//Params(param=阿柴该还花呗了。)
        //Params(param=阿柴该还花呗了。)
		//阿柴该还京东白条了。

﹝isValid﹞

isValid:验证 JSON 是否合规。详细内容请查看 JSONSchema 代码。

        String schemaString = "{\"type\": \"object\", \"properties\": {\"name\": {\"type\": \"string\"}}, \"required\": [\"name\"]}";
        JSONSchema jsonSchema = JSONSchema.parseSchema(schemaString);

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");

        JSONObject jsonAnother = new JSONObject();
        jsonAnother.put("age", 18);

        boolean valid = json.isValid(jsonSchema);
        boolean validAnother = jsonAnother.isValid(jsonSchema);

        System.out.println(valid);
        System.out.println(validAnother);

		//true
		//false

﹝toJSONString﹞

toJSONString:将 JSONObject 序列化成字符串,序列化的时候可以使用 JSONWriter.Feature 中的枚举类来进行自定义序列化。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");
        
        String jsonString = json.toJSONString();
        System.out.println(jsonString);

		//{"name":"阿柴","age":18,"sex":"男","address":"北京市"}

﹝toString﹞

toString:将对象序列化,和 toJSONString 的结果是一样的。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        String jsonString = json.toString();
        System.out.println(jsonString);

		//{"name":"阿柴","age":18,"sex":"男","address":"北京市"}

﹝compute﹞

compute:是从 HashMap 那里继承过来的方法,对特定的 Key 值进行操作,并最终返回的方法。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        Object name = json.compute("name", (key, value) -> "+" + value + "+");

        System.out.println(name);

		//+阿柴+

﹝computeIfAbsent﹞

computeIfAbsent:也是从 HashMap 继承来的方法,当Key值存在的时候返回当前值,如果不存在插入键值对。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        Object name = json.computeIfAbsent("name", (key) -> "阿柴的哥哥");
        Object brother = json.computeIfAbsent("brother", (key) -> "阿柴的哥哥");

        System.out.println(name);
        System.out.println(brother);
        System.out.println(json);
		
		//阿柴
		//阿柴的哥哥
		//{"name":"阿柴","age":18,"sex":"男","address":"北京市","brother":"阿柴的哥哥"}

﹝computeIfPresent﹞

computeIfPresent:如果 key 对应的 value 不存在,则返回 null ,如果存在则返回通过 remappingFunction 重新计算后的值。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        Object name = json.computeIfPresent("name", (key, value) -> value + "+++");
        Object brother = json.computeIfPresent("brother", (key, value) -> value + "+++");

        System.out.println(name);
        System.out.println(brother);

		//阿柴+++
		//null

﹝entrySet﹞

entrySet:获取 entrySet 键值对集合。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");


        Set<Map.Entry<String, Object>> entries = json.entrySet();
        entries.forEach((item) -> System.out.println(item.getKey() + "---" + item.getValue()));

		//name---阿柴
		//age---18
		//sex---男
		//address---北京市

﹝keySet﹞

keySet:获取 Key 的集合。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        Set<String> keySet = json.keySet();
        keySet.forEach(System.out::println);

		//name
		//age
		//sex
		//address

﹝values﹞

values:获取值得集合。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        Collection<Object> values = json.values();
        values.forEach(System.out::println);

﹝isEmpty﹞

isEmpty:判空操作,很简单了,不进行解释了。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        boolean empty = json.isEmpty();
        System.out.println(empty);

		//false

﹝merge﹞

merge:如果不存在将新的值赋值到 key ,如果存在更新 key 对应的 value。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        Object merge = json.merge("name", "黑柴", (key, value) -> value + "Test");

        System.out.println(merge);

		//黑柴Test

﹝remove﹞

remove:移除指定的键值对。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        json.remove("address");

        System.out.println(json);
		
		//{"name":"阿柴","age":18,"sex":"男"}

﹝replace﹞

replace:替换指指定的键值对。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        json.replace("name", "黑柴");

        System.out.println(json);

		//{"name":"黑柴","age":18,"sex":"男","address":"北京市"}

﹝size﹞

size:获取对象的长度。

        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        int size = json.size();

        System.out.println(size);
            
        //4

﹝clear﹞

clear:清空当前对象。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        json.clear();

        System.out.println(json);

﹝equals﹞

equals:比较方法,可以和 JSONObject,Map 进行比较。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");

        Map<String, String> map = new HashMap<>();
        map.put("name", "阿柴");

        boolean equals = json.equals(map);

        System.out.println(equals);

		//true

﹝forEach﹞

forEach:对 JSONObject 对象进行遍历。这里要注意在 forEach 方法中,对 key,value 做更改是不会影响原对象的。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        json.forEach((key, value) -> System.out.println(key + "---" + value));

		//name---阿柴
		//age---18
		//sex---男
		//address---北京市

﹝hashCode﹞

hashCode:获取哈希值。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        int hashCode = json.hashCode();
        
        System.out.println(hashCode);

		//-1157924043

﹝replaceAll﹞

replaceAll:对所有的值进行替换。

        JSONObject json = new JSONObject();
        json.put("name", "阿柴");
        json.put("age", 18);
        json.put("sex", "男");
        json.put("address", "北京市");

        json.replaceAll((key, value) -> value + "Test");
        System.out.println(json);

		//{"name":"阿柴Test","age":"18Test","sex":"男Test","address":"北京市Test"}

﹝parseObject﹞﹝static﹞

将字符串反序列化成 Java 对象。

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("msg", "黑柴是阿柴的妹妹!");

        Message message = JSONObject.parseObject(jsonObject.toJSONString(), Message.class);

        System.out.println(message);

﹝toJSONString﹞﹝static﹞

将对象序列化成字符串。

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("msg", "黑柴是阿柴的妹妹!");

        String message = JSONObject.toJSONString(jsonObject);

        System.out.println(message);

﹝of﹞﹝static﹞

快速生成 JSONObject 对象。

        JSONObject of = JSONObject.of("1", "1", "2", "2", "3", "3");

        System.out.println(of);

﹝parse﹞﹝static﹞

将字符串序列化成 JSONObject 对象。和 parseObject 作用一样,但是可以传入 JSONReader.Feature。

        String str = "{\"1\":\"1\",\"2\":\"2\",\"3\":\"3\"}";

        JSONObject parse = JSONObject.parse(str);

        System.out.println(parse);

『@JSONField』

@JSONField 是 FastJson 库中的一个注解,用于控制 JSON 序列化和反序列化时的行为。通过在 Java 类的属性上添加 @JSONField 注解,可以指定属性在 JSON 中的名称、顺序、格式化方式等。

@JSONField 的属性

属性作用
name【序列化】会将原本的属性变成name设置的属性。
alternateNames【反序列化】会将别名的属性一同反序列化。
defaultValue【反序列化】如果没有匹配值,会设置默认值。
ordinal【序列化】指定序列化的顺序。【没有设置该属性的字段默认为0】
format【序列化】用在Date属性上,自动格式化日期。
jsonDirect【序列化】针对值为json字符串的字段,,true则序列化, 默认为false,不序列化的话会有转义符存在。
label【序列化】可以给属性设置标签,这样可以批量处理某一类的属性,不设置则默认序列化。
serialize【序列化】可以指定字段是否参加序列化,默认为True,当为False的时候不参加序列化。
deserialize【反序列化】可以指定字段是否参加反序列化,默认为True,当为False的时候不参加反序列化。
serializeFeatures【序列化】可以制定序列化的特点。
deserializeFeatures【反序列化】可以制定反序列化的特点。
serializeUsing【序列化】可以自定义序列化。
deserializeUsing【反序列化】可以自定义反序列化。
unwrapped【序列化】若为Ture,相当于把子对象的属性,添加到父对象中,不再显示子对象。默认为false。

总体示例

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.project.missionnel.bean.Message;
import com.ruoyi.project.missionnel.bean.Student;

import java.util.Date;

public class Main {
    public static void main(String[] args) throws JsonProcessingException {

        Student student = Student.builder()
                .name("阿柴")
                .age(20)
                .gender("男")
                .job("自由工作者")
                .address("北京市中南海")
                .brother("黑柴")
                .sister("白柴")
                .birthday(new Date())
                .json("{\"word\":\"xxx\"}")
                .message(new Message("获得了录取通知书!"))
                .build();

        String serializeStr = JSON.toJSONString(student);
        System.out.println(serializeStr);

        Student studentNew = JSON.parseObject(serializeStr, Student.class);
        System.out.println(studentNew);

    }
}

label 属性示例

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.Labels;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.project.missionnel.bean.Student;

public class Main {
    public static void main(String[] args) throws JsonProcessingException {

        Student student = Student.builder()
                .name("阿柴")
                .age(20)
                .build();

        String serializeStr = JSON.toJSONString(student, Labels.excludes("ELS"));
        System.out.println(serializeStr);

    }
}

alternateNames 属性示例

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.project.missionnel.bean.Student;

public class Main {
    public static void main(String[] args) throws JsonProcessingException {

        String str ="{\"myName\":\"汉族\",\"age\":18}";

        Student student = JSON.parseObject(str, Student.class);
        System.out.println(student);

    }
}

『NameFilter』

NameFilter是FastJson中的一个接口,用于在序列化和反序列化过程中控制字段的命名。通过实现NameFilter接口,可以自定义字段的命名规则,从而实现特定的需求。

本身在银行工作,对接数据源,不同的数据源序列化的字段是不一样的,所以有了下面的案例。根据不同的Type,序列化成不同的值。

﹝Main﹞

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.project.missionnel.annotate.AliasFilter;
import com.ruoyi.project.missionnel.bean.Message;

public class Main {
    public static void main(String[] args) throws JsonProcessingException {

        Message message = new Message("阿柴会吃肉!");
        String small = JSON.toJSONString(message, new AliasFilter("Small"));
        String big = JSON.toJSONString(message, new AliasFilter("Big"));
        System.out.println(small);
        System.out.println(big);
        
        //{"message":"阿柴会吃肉!"}
		//{"MESSAGE":"阿柴会吃肉!"}

    }
}

﹝Another Method﹞

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.NameFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.project.missionnel.bean.User;

import static com.alibaba.fastjson2.PropertyNamingStrategy.UpperCase;

public class Main {
    public static void main(String[] args) throws JsonProcessingException {

        // 第一种生成NameFilter的方法。
        NameFilter camelCase = NameFilter.of(UpperCase);

        // 第二种生成NameFilter的方法,使用拉姆达表达式来构建。
        NameFilter filter = (Object object, String name, Object value) -> "test" + name;

        // NameFilter的static方法,没有找到应用场景。写在这里作为展示用法。
        NameFilter compose = NameFilter.compose(filter, camelCase);

        User user = new User().setName("阿柴").setAge("18").setSex("男").setHeight("186");

        String jsonString = JSON.toJSONString(user, compose);

        System.out.println(jsonString);
        
        //{"TESTAGE":"18","TESTHEIGHT":"186","TESTNAME":"阿柴","TESTSEX":"男"}

    }
}

『ValueFilter』

ValueFilter 和 NameFilter的使用方式一样,不再做其他展示。

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.ValueFilter;
import com.ruoyi.project.missionnel.bean.User;

public class Main {
    public static void main(String[] args) {

        ValueFilter pre = (Object object, String name, Object value) -> "pre_" + value;
        ValueFilter suf = (Object object, String name, Object value) -> value + "_suf";

        // ValueFilter的static方法,没有找到应用场景。写在这里作为展示用法。
        ValueFilter filter = ValueFilter.compose(pre, suf);

        User user = new User().setName("阿柴").setAge("18").setSex("男").setHeight("186");

        String jsonString = JSON.toJSONString(user, filter);

        System.out.println(jsonString);

        //{"age":"18_suf","height":"186_suf","name":"阿柴_suf","sex":"男_suf"}

    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Fastjson是一个Java语言编写的高性能JSON处理库,可以实现JSON字符串与Java对象之间的相互转换。下面是一个简单的示例,演示了如何使用Fastjson进行JSON的序列化和反序列化: 1. 导入Fastjson的依赖包到你的项目中。你可以在Maven或Gradle配置文件中添加以下依赖: ```xml <!-- Maven --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.78</version> </dependency> // Gradle implementation 'com.alibaba:fastjson:1.2.78' ``` 2. 创建一个Java对象,例如: ```java public class Person { private String name; private int age; // getters and setters } ``` 3. 将Java对象转换为JSON字符串: ```java import com.alibaba.fastjson.JSON; Person person = new Person(); person.setName("John"); person.setAge(25); String jsonString = JSON.toJSONString(person); System.out.println(jsonString); ``` 这将输出以下JSON字符串: ```json {"age":25,"name":"John"} ``` 4. 将JSON字符串转换为Java对象: ```java String jsonString = "{\"name\":\"John\",\"age\":25}"; Person person = JSON.parseObject(jsonString, Person.class); System.out.println(person.getName()); System.out.println(person.getAge()); ``` 这将输出: ``` John 25 ``` 这只是Fastjson的基本用法示例,你还可以使用Fastjson进行更复杂的JSON处理操作,例如处理嵌套对象、数组等。你可以参考Fastjson的官方文档(https://github.com/alibaba/fastjson/wiki/Quick-Start)了解更多用法和功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值