fastjson(五)通过SerializeFilter定制序列化

通过SerializeFilter可以使用扩展编程的方式实现定制序列化。fastjson提供了多种SerializeFilter:

  • PropertyPreFilter 根据PropertyName判断是否序列化;
  • PropertyFilter 根据PropertyName和PropertyValue来判断是否序列化;
  • NameFilter 修改Key,如果需要修改Key,process返回值则可;
  • ValueFilter 修改Value;
  • BeforeFilter 序列化时在最前添加内容;
  • AfterFilter 序列化时在最后添加内容。

下面来看示例代码:

示例对象:

package json.fastjson.SerializeFilter;

public class User {

    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
}
一、PropertyFilter 根据PropertyName和PropertyValue来判断是否序列化

PropertyFilter 接口:

  public interface PropertyFilter extends SerializeFilter {
      boolean apply(Object object, String propertyName, Object propertyValue);
  }

可以通过扩展实现根据object或者属性名称或者属性值进行判断是否需要序列化。例如:

package json.fastjson.SerializeFilter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.PropertyFilter;

public class TestPropertyFilter {

    public static void main(String[] args) {
        PropertyFilter filter = new PropertyFilter() {

            @Override
            public boolean apply(Object source, String name, Object value) {

                System.out.println("----------------source=" + source);
                System.out.println("----------------name=" + name);
                System.out.println("----------------value=" + value);
                System.out.println("");
                // 属性是id并且大于等于100时进行序列化
                if ("id".equals(name)) {
                    long id = ((Long) value).longValue();
                    return id >= 100;
                }
                return false;
            }
        };

        User user = new User();
        user.setId(9L);
        user.setName("挖坑埋你");

        String jsonString = JSON.toJSONString(user, filter); // 序列化的时候传入filter
        System.out.println("序列化,id=9:" + jsonString + "\n");

        user.setId(200L);
        jsonString = JSON.toJSONString(user, filter); // 序列化的时候传入filter
        System.out.println("序列化,id=200:" + jsonString);
    }

}

输出结果:

----------------source=User [id=9, name=挖坑埋你]
----------------name=id
----------------value=9

----------------source=User [id=9, name=挖坑埋你]
----------------name=name
----------------value=挖坑埋你

序列化,id=9:{}

----------------source=User [id=200, name=挖坑埋你]
----------------name=id
----------------value=200

----------------source=User [id=200, name=挖坑埋你]
----------------name=name
----------------value=挖坑埋你

序列化,id=200:{"id":200}
二、NameFilter 序列化时修改Key

NameFilter 接口:

public interface NameFilter extends SerializeFilter {
    String process(Object object, String propertyName, Object propertyValue);
}

如果需要修改Key,process返回值则可,例如:

package json.fastjson.SerializeFilter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.PascalNameFilter;

public class TestNameFilter {

    public static void main(String[] args) {
        User user = new User();
        user.setId(9L);
        user.setName("挖坑埋你");

        String jsonString = JSON.toJSONString(user); // 序列化的时候传入filter
        System.out.println("普通序列化:" + jsonString + "\n");

        NameFilter filter = new NameFilter() {

            @Override
            public String process(Object object, String name, Object value) {
                System.out.println("----------------object=" + object);
                System.out.println("----------------name=" + name);
                System.out.println("----------------value=" + value);
                System.out.println("");
                // 属性是id是修改id的名字
                if ("id".equals(name)) {
                    return name + "$";
                }
                return name;
            }
        };

        jsonString = JSON.toJSONString(user, filter); // 序列化的时候传入filter
        System.out.println("NameFilter序列化:" + jsonString + "\n");

        // fastjson内置一个PascalNameFilter,用于输出将首字符大写的Pascal风格
        jsonString = JSON.toJSONString(user, new PascalNameFilter()); // 序列化的时候传入filter
        System.out.println("PascalNameFilter序列化:" + jsonString + "\n");
    }

}

输出结果:

普通序列化:{"id":9,"name":"挖坑埋你"}

----------------object=User [id=9, name=挖坑埋你]
----------------name=id
----------------value=9

----------------object=User [id=9, name=挖坑埋你]
----------------name=name
----------------value=挖坑埋你

NameFilter序列化:{"id$":9,"name":"挖坑埋你"}

PascalNameFilter序列化:{"Id":9,"Name":"挖坑埋你"}
三、ValueFilter 序列化时修改Value

ValueFilter 接口:

  public interface ValueFilter extends SerializeFilter {
      Object process(Object object, String propertyName, Object propertyValue);
  }

如果需要修改Value,process返回值则可,例如:

package json.fastjson.SerializeFilter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.ValueFilter;

public class TestValueFilter {

    public static void main(String[] args) {
        User user = new User();
        user.setId(9L);
        user.setName("挖坑埋你");

        String jsonString = JSON.toJSONString(user); // 序列化的时候传入filter
        System.out.println("普通序列化:" + jsonString + "\n");

        ValueFilter filter = new ValueFilter() {

            @Override
            public Object process(Object object, String name, Object value) {
                System.out.println("----------------object=" + object);
                System.out.println("----------------name=" + name);
                System.out.println("----------------value=" + value);
                System.out.println("");
                // 属性是id时修改id的值
                if ("id".equals(name)) {
                    long id = ((Long) value).longValue();
                    return id + "$";
                }
                return value;
            }
        };

        jsonString = JSON.toJSONString(user, filter); // 序列化的时候传入filter
        System.out.println("ValueFilter序列化:" + jsonString + "\n");
    }

}

输出结果:

普通序列化:{"id":9,"name":"挖坑埋你"}

----------------object=User [id=9, name=挖坑埋你]
----------------name=id
----------------value=9

----------------object=User [id=9, name=挖坑埋你]
----------------name=name
----------------value=挖坑埋你

ValueFilter序列化:{"id":"9$","name":"挖坑埋你"}
四、BeforeFilter 序列化时在最前添加内容

BeforeFilter 接口:

  public abstract class BeforeFilter implements SerializeFilter {
      protected final void writeKeyValue(String key, Object value) { ... }
      // 需要实现的抽象方法,在实现中调用writeKeyValue添加内容
      public abstract void writeBefore(Object object);
  }

在序列化对象的所有属性之前执行某些操作,例如调用 writeKeyValue 添加内容:

package json.fastjson.SerializeFilter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.BeforeFilter;

public class TestBeforeFilter {

    public static void main(String[] args) {
        User user = new User();
        user.setId(9L);
        user.setName("挖坑埋你");

        String jsonString = JSON.toJSONString(user); // 序列化的时候传入filter
        System.out.println("普通序列化:" + jsonString + "\n");

        BeforeFilter filter = new BeforeFilter() {

            @Override
            public void writeBefore(Object object) {

                System.out.println("----------------object=" + object);

                User user = (User) object;
                System.out.println("----------------User.id=" + user.getId() + " " + "User.name=" + user.getName() + "\n");
                user.setName(user.getName() + "$$$");
            }
        };

        jsonString = JSON.toJSONString(user, filter); // 序列化的时候传入filter
        System.out.println("BeforeFilter序列化:" + jsonString + "\n");
    }

}

输出结果:

普通序列化:{"id":9,"name":"挖坑埋你"}

----------------object=User [id=9, name=挖坑埋你]
----------------User.id=9 User.name=挖坑埋你

BeforeFilter序列化:{"id":9,"name":"挖坑埋你$$$"}
五、AfterFilter 序列化时在最后添加内容

AfterFilter 接口:

  public abstract class AfterFilter implements SerializeFilter {
      protected final void writeKeyValue(String key, Object value) { ... }
      // 需要实现的抽象方法,在实现中调用writeKeyValue添加内容
      public abstract void writeAfter(Object object);
  }

在序列化对象的所有属性之后执行某些操作,例如调用 writeKeyValue 添加内容,例如:

package json.fastjson.SerializeFilter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.AfterFilter;

public class TestAfterFilter {

    public static void main(String[] args) {
        User user = new User();
        user.setId(9L);
        user.setName("挖坑埋你");

        String jsonString = JSON.toJSONString(user); // 序列化的时候传入filter
        System.out.println("普通序列化:" + jsonString + "\n");

        AfterFilter filter = new AfterFilter() {

            @Override
            public void writeAfter(Object object) {

                User user = (User) object;
                System.out.println("------------User.id=" + user.getId() + " " + "User.name=" + user.getName() + "\n");
                user.setName(user.getName() + "$$$");
            }
        };

        jsonString = JSON.toJSONString(user, filter); // 序列化的时候传入filter
        System.out.println("AfterFilter序列化:" + jsonString + "\n");
        System.out.println(user);
    }

}

输出结果:

普通序列化:{"id":9,"name":"挖坑埋你"}

------------User.id=9 User.name=挖坑埋你

AfterFilter序列化:{"id":9,"name":"挖坑埋你"}

User [id=9, name=挖坑埋你$$$]
  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fastjson2 中,可以通过实现 SerializerFeature 和 Feature 接口来实现全局枚举的序列化和反序列化。 1. 全局枚举的序列化 可以通过实现 SerializerFeature 接口来实现全局枚举的序列化,例如: ```java public enum MyEnum { A, B, C; } public class MyEnumSerializer implements ContextValueSerializer, SerializerFeature { @Override public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { if (object == null) { serializer.getWriter().writeNull(); return; } Enum<?> e = (Enum<?>) object; serializer.getWriter().writeValue(e.ordinal()); } @Override public boolean writeAsArray() { return false; } @Override public boolean writeNull() { return true; } @Override public boolean writeEnumUsingName() { return false; } @Override public boolean writeEnumUsingToString() { return false; } @Override public boolean writeEnumUsingOrdinal() { return true; } @Override public boolean writeSlashAsSpecial() { return false; } @Override public boolean writeTabAsSpecial() { return false; } @Override public boolean writeQuoteCharAsSpecial() { return false; } @Override public boolean writeSingleQuoteAsChar() { return false; } @Override public boolean writeClassName() { return false; } @Override public boolean notWriteDefaultValue() { return false; } @Override public boolean browserSecure() { return false; } @Override public boolean writeDateUseDateFormat() { return false; } @Override public boolean sortField() { return false; } @Override public boolean writeTab() { return false; } @Override public boolean prettyFormat() { return false; } @Override public boolean writeContentLength() { return false; } @Override public boolean quoteFieldNames() { return false; } @Override public boolean useSingleQuotes() { return false; } @Override public boolean writeNonStringValueAsString() { return false; } @Override public boolean notWriteRootClassName() { return false; } @Override public boolean beanToArray() { return false; } @Override public boolean writeBigDecimalAsPlain() { return false; } @Override public boolean ignoreNonFieldGetter() { return false; } @Override public boolean writeEnumUsingToStringUsingGlobalSetting() { return false; } @Override public boolean writeEnumUsingNameUsingGlobalSetting() { return false; } @Override public boolean writeDirect() { return false; } @Override public boolean browserCompatible() { return false; } } ``` 然后,在初始化 JSON 序列化器时,可以将该序列化器添加到全局的 SerializerFeature 中,例如: ```java SerializeConfig config = new SerializeConfig(); config.put(MyEnum.class, MyEnumSerializer.INSTANCE); JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.config(JSON.DEFAULT_GENERATE_FEATURE, MyEnum.class); ``` 这样,无论什么时候序列化 MyEnum 类型的枚举值,都会使用 MyEnumSerializer 中定义的方式进行序列化。 2. 全局枚举的反序列化 可以通过实现 Feature 接口来实现全局枚举的反序列化,例如: ```java public enum MyEnum { A, B, C; } public class MyEnumFeature implements Feature { @Override public int getMask() { return 0; } @Override public boolean isEnabled(int features) { return true; } @Override public boolean isEnabled(int features, int feature) { return true; } @Override public int config(int features, int feature, boolean state) { if (feature == MyEnumFeature.WRITE_ENUM_USING_ORDINAL.mask) { return state ? features | MyEnumFeature.WRITE_ENUM_USING_ORDINAL.mask : features & ~MyEnumFeature.WRITE_ENUM_USING_ORDINAL.mask; } return features; } public static final MyEnumFeature WRITE_ENUM_USING_ORDINAL = new MyEnumFeature(1); public static final MyEnumFeature WRITE_ENUM_USING_NAME = new MyEnumFeature(2); private final int mask; private MyEnumFeature(int mask) { this.mask = mask; } } ``` 然后,在初始化 JSON 解析器时,可以将该 Feature 添加到全局的 Feature 中,例如: ```java ParserConfig config = new ParserConfig(); config.addCompatibleFeature(MyEnumFeature.WRITE_ENUM_USING_ORDINAL); JSON.DEFAULT_PARSER_FEATURE |= MyEnumFeature.WRITE_ENUM_USING_ORDINAL.mask; ``` 这样,无论什么时候反序列化 MyEnum 类型的枚举值,都会使用 MyEnumFeature 中定义的方式进行反序列化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值