FastJson-JSONField

本文介绍了FastJson的JSONField注解在序列化中的使用,包括如何配置辅助序列化功能,以及两种定制字段输出的方式。在遇到@JSONField定制不生效的问题时,官方建议更新至fastjson-1.1.42以上版本。为了解决定制与复用VO的冲突,文章提出了通过反射获取注解值并结合NameFilter过滤器的方法,同时提到了FastJson的PropertyFilter和ValueFilter过滤器的类似用途。

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

学习摘要自
https://github.com/alibaba/fastjson
http://blog.youkuaiyun.com/zimo2013/article/details/10474107

Maven依赖
仓库地址
http://repo1.maven.org/maven2/com/alibaba/fastjson/
选择版本、建议使用最新版本

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

最常用的工具类和两个方法

JSON 序列化对象为json文本,包括普遍Javabean,Map,List,嵌套对象
JSON.toJSONString(Object object) 序列化对象
JSON.toJSONString(Object object, boolean prettyFormat),序列化对象,并以良好的格式呈现

例如

    @Test
    public void testJSonBean() throws Exception {
        Model m = new Model(); //普通Java VO
        m.setName("xiele");
        m.setDate(new Date());
        m.setIg(1);
        m.setLg(1000L);
        System.out.println(JSON.toJSONString(m));
    }
    输出的文本:
    {"name":"xiele","date":1437487740477,"lg":1000,"ig":1}

    如果带上prettyFormat为true
    JSON.toJSONString(m,true)
    {
    "name":"xiele",
    "date":1437487867654,
    "lg":1000,
    "ig":1
}

配置一些辅助的序列化功能(SerialFeature)

public static final String toJSONString(Object object, SerializerFeature... features)

参考源码
public enum SerializerFeature {
    QuoteFieldNames, //序列化输出含引号的字段,默认
    UseSingleQuotes, //使用单引号而不是双引号序列化
    WriteMapNullValue, //空值是否输出,默认不输出null
    WriteEnumUsingToString,Enum输出为枚举值
    UseISO8601DateFormat, //Date使用ISO8601格式输出日期
    WriteNullListAsEmpty,//list字段如果为null,输出为[],而不是null,默认不输出null
    WriteNullStringAsEmpty,//字符串类型为null,输出""(空串)
    WriteNullNumberAsZero, //数值字段如果为null,输出为0,而不是null
    WriteNullBooleanAsFalse, //Boolean字段如果为null,输出为false,而不是null
    SkipTransientField, //忽略@Transient注解过的字段
    SortField //按字段名称排序后输出
  }

用法

JSON.toJSONString(m,SerializerFeature.UseISO8601DateFormat)

定制序列化
在做网关开发时,为移动端提供的很多数据都需要简化处理,比如VO的key需要定制输出,可使用FastJson提供的@JSONField注解。
@JSONField有两种方式
1.在字段上
2.在属性getter方法上
例如

 public class VO {
      @JSONField(name="ID")
      private int id;
 }
 public class VO {
      private int id;

      @JSONField(name="ID")
      public int getId() { return id;}
 }

但是
在使用FastJson的@JSONField做定制时,偶尔不生效,也包含了继承的情况,有时候会出现结果不一致。
官方给出的解释是版本过低,升级到fastjson-1.1.42及其以后即可。
https://github.com/alibaba/fastjson/issues/176

需求是变化的,尽管有时候需要定制,有的终端需要定制,但是又需要复用发布出去的VO,但是需要解除由@JSONField定制带来的困扰。
解决办法,是通过反射找到VO的字段Field,然后得到其注解,并获取到注解的值,最后存入Map中,使得定制的名称和原来的字段名形成Key-Value绑定。再通过FastJson提供的NameFilter名称过滤器来过滤序列的名称。

获取注解的值

    @Test
    public void testGetFieldAnno() throws Exception {
        Map<String, String> map = Maps.newHashMap();
        Model m = new Model();
        Field[] fs =  m.getClass().getDeclaredFields();
        for (Field f : fs) {
            if (f.isAnnotationPresent(JSONField.class)) {
                JSONField jf = f.getAnnotation(JSONField.class);
                map.put(jf.name(), f.getName());
            }
        }
        System.out.println(JSON.toJSONString(map,true));
    }

过滤名称

 @Test
    public void testMapJSonField()  {
        Model m = new Model();
        m.setName("xiele");
        m.setDate(new Date());
        m.setIg(1);
        m.setLg(1000L);

        final  Map<String, String> map = Maps.newHashMap();
        Field[] fs =  m.getClass().getDeclaredFields();
        for (Field f : fs) {
            if (f.isAnnotationPresent(JSONField.class)) {
                JSONField jf = f.getAnnotation(JSONField.class);
                map.put(jf.name(), f.getName());
            }
        }

        System.out.println(JSON.toJSONString(map,true));

        NameFilter filter = new NameFilter() {
            @Override
            public String process(Object source, String name, Object value) {
                // source是当前对象, name是key, value实在值
                return map.get(name);
            }
        };

        JSONSerializer jsonSerializer = new JSONSerializer();
        jsonSerializer.getNameFilters().add(filter); // 通过增加一个过滤器,为name和值进行过滤
        jsonSerializer.write(m);
        System.out.println(jsonSerializer.toString());
    }

除此之外,FastJson还提供了属性过滤器PropertyFilter、值过滤器ValueFilter,用法类似。

Fastjson是一个Java语言编写的JSON处理库,@JSONFieldFastjson提供的注解之一。 @JSONField注解用于指示在序列化和反序列化过程中如何处理Java对象的字段。它可以应用于类的字段或者类的setter和getter方法,并提供了一些属性来自定义字段的行为。 使用@JSONField注解,可以实现以下功能: 1. 指定字段的名称:通过设置name属性,可以指定将Java对象字段序列化为JSON时的字段名称。例如: ``` @JSONField(name = "id") private int userId; ``` 以上代码将Java对象中的userId字段序列化为JSON时,字段名为"id"。 2. 排除字段:通过设置serialize属性为false,可以在序列化对象时排除这个字段。例如: ``` @JSONField(serialize = false) private String password; ``` 以上代码将在序列化对象时,忽略password字段。 3. 指定字段的格式化方式:通过设置format属性,可以指定字段序列化和反序列化时所使用的格式。例如: ``` @JSONField(format = "yyyy-MM-dd") private Date createTime; ``` 以上代码将使用"yyyy-MM-dd"格式处理createTime字段。 4. 自定义字段的序列化和反序列化逻辑:通过设置serializeUsing和deserializeUsing属性,可以指定自定义的序列化和反序列化器来处理字段。例如: ``` @JSONField(serializeUsing = CustomSerializer.class) private SomeObject someObject; ``` 以上代码将使用CustomSerializer来序列化someObject字段。 总之,@JSONFieldFastjson中一个非常有用的注解,可以通过它来控制字段的序列化和反序列化方式,实现更加灵活的JSON数据处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值