FastJson 自定义Serialize、Parser

本文介绍了在处理FastJson时遇到的枚举类型为int的反序列化问题。由于FastJson默认按枚举顺序解析int类型,但实际值可能不对应顺序,因此需要自定义解析器。通过实现`objectDeserializer`接口进行反序列化,`ObjectSerializer`接口进行序列化,解决了此问题。此外,还提到自定义序列化、反序列化方法在处理日期和时间类型时也常见。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


FastJson 自定义Serialize、Parser

今天在处理Json反序列化时,在C#传过来的JSON字符串中枚举类型为int类型,FastJson对于枚举的处理有两种类型,一种是字符串一种是int类型,但是它自带的解析int是按照枚举的顺序来解析的,但是有时候值不一定和顺序相对应,所以使用自定义解析器方式进行解决。在网上找解决方案,没找到详细的方法。通过查看源代码得出解决方案
以解析如下枚举为例:

public enum Status {

    Ready(10),

    Completed(20);

    private int value;

    private Status(int value) {
        this.value = value;
    }

    public static Status create(int value) {
        switch (value) {
        case 10:
            return Status.Ready;
        case 20:
            return Status.Completed;
        default:
            throw new RuntimeException("code error");
        }
    }

    public static int value(Status status){
        return status.value;
    }
}

反序列化过程实现objectDeserializer接口,以上枚举代码如下:

public class StatusDeserializer implements ObjectDeserializer {

    public <T> T deserialze(DefaultJSONParser parser, Type type,
            Object fieldName) {
        JSONLexer lexer = parser.getLexer();
        int value = lexer.intValue();
        return (T) Status.create(value);
    }

    public int getFastMatchToken() {
        // TODO Auto-generated method stub
        return 0;
    }
}

序列化过程实现ObjectSerializer接口

public class StatusSerializer implements ObjectSerializer{

    public void write(JSONSerializer serializer, Object object,
            Object fieldName, Type fieldType) throws IOException {
        SerializeWriter out = serializer.getWriter();
         if (object == null) {
                serializer.getWriter().writeNull();
                return;
            }
         out.write(Status.value((Status)object));
    }
}

使用自定义的序列化和反序列化的方法如下:
序列化过程

        SerializeConfig config=new SerializeConfig();
        config.put(Status.class, new StatusSerializer());
        String jsonStr=JSON.toJSONString(test,config);

反序列化过程

        ParserConfig.getGlobalInstance().putDeserializer(Status.class, new StatusDeserializer());
        Test test1=JSON.parseObject(jsonStr,Test.class);

除了处理枚举类型时,有时需要自定义序列化、反序列化方法外,在处理日期、时间等类型时也经常需要自己实现。


### fastjson 忽略字段或方法的序列化与反序列化 在使用 `fastjson` 进行 JSON 的序列化和反序列化操作时,可以通过多种方式来忽略特定字段或方法。以下是具体的方式及其说明: #### 1. 使用 `@JSONField(serialize=false)` 注解 通过 `@JSONField` 注解中的 `serialize` 属性可以控制某个字段是否参与序列化。当设置为 `false` 时,该字段不会被序列化到最终的 JSON 字符串中。 ```java import com.alibaba.fastjson.annotation.JSONField; public class User { private String username; @JSONField(serialize = false) private String password; // getters and setters } ``` 在此示例中,`password` 字段将不会出现在序列化后的 JSON 中[^1]。 --- #### 2. 使用 `transient` 关键字 Java 提供了 `transient` 关键字,标记的字段会被视为临时变量,在序列化过程中会自动跳过这些字段。 ```java public class User { private String username; transient private String password; // getters and setters } ``` 这里,`password` 字段由于被声明为 `transient`,因此它不会被包含在序列化结果中[^5]。 --- #### 3. 实现自定义序列化过滤器 如果需要更加灵活地控制哪些字段应该被忽略,则可以实现 `SerializeFilter` 接口并提供自定义逻辑。 ```java import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson.serializer.PropertyPreFilter; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.ObjectSerializer; import java.lang.reflect.Type; public class CustomFilter implements PropertyPreFilter { @Override public boolean apply(Object source, String name, Object value) { // 如果字段名为 "password" 则返回 false 表示忽略此字段 return !"password".equals(name); } } // 调用时传入过滤器 User user = new User(); System.out.println(JSON.toJSONString(user, new CustomFilter())); ``` 这种方式适用于动态决定哪些字段应被排除的情况[^3]。 --- #### 4. 配置全局序列化规则 除了针对单个类配置外,还可以通过调整 `SerializerFeature` 来影响整个项目的默认行为。例如,启用 `SkipTransientField` 特性可让所有带有 `transient` 的字段都被自动忽略。 ```java String jsonString = JSON.toJSONString(obj, SerializerFeature.SkipTransientField); ``` 这使得无需逐一手动标注即可达到一致的效果[^4]。 --- #### 5. 反序列化时忽略未知字段 对于反序列化而言,默认情况下未匹配上的额外字段会被丢弃而不会抛出异常。但如果希望显式指定某些字段不应读取回来,则可通过编写自定义解析器完成。 ```java import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import java.lang.reflect.Type; public class IgnoreFieldsDeserilizer<T> implements ObjectDeserializer { @SuppressWarnings("unchecked") @Override public T deserialze(DefaultExtJSONParser parser, Type type, Object fieldName) { // 自定义逻辑... return (T)new YourClass(); // 返回对象实例 } @Override public int getFastMatchToken() { return 0; // 默认值 } } ``` 随后注册这个 Deserializer 即可生效[^4]。 --- ### 总结 以上介绍了几种常见的策略用来解决如何利用 fastjson 忽略不需要处理的数据项问题。开发者可以根据项目实际情况选择最适合自己的方案实施。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值