FastJSON解析-----@JSONField注解详解

一、依赖

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

二、FastJson序列化方式  

    PS:这里只陈述第一种方式。

  • 通过@JSONField定制序列化-----配置在字段或者getter/setter方法上。
  • 通过@JSONType定制序列化-----配置在类上
  • 通过SerializeFilter定制序列化 
  • 通过ParseProcess定制反序列化

三、@JSONField

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})//一般作用在字段上
public @interface JSONField {
    int ordinal() default 0;//配置序列化和反序列化的顺序

    String name() default "";//配置序列化和反序列化时字段的名字

    String format() default "";//字段格式化,对日期很有用

    boolean serialize() default true;//是否序列化

    boolean deserialize() default true;//是否反序列化

    SerializerFeature[] serialzeFeatures() default {};//控制序列化的一些规则,如NULL的处理

    Feature[] parseFeatures() default {};//控制反序列化的一些规则

    String label() default "";

    boolean jsonDirect() default false;//当有一个字段是字符串类型,里面是json格式数据,希望直接输入,而不是经过转义之后再输出。

    Class<?> serializeUsing() default Void.class;//对某一个类的某个属性定制序列化

    Class<?> deserializeUsing() default Void.class;//对某一个类的某个属性定制反序列化

    String[] alternateNames() default {};//反序列化时使用多个不同的字段名称
}
  • ordinal
@Data
public class User {
    @JSONField(ordinal = 2)
    private String name;

    @JSONField(ordinal = 3)
    private String sex;

    @JSONField(ordinal = 1)
    private Integer age;
}
//序列化结果:顺序为age、name、sex
{"age":20,"name":"zhangsan","sex":"男"}
  •  name
@Data
public class User {
    @JSONField(ordinal = 2 , name="userName")
    private String name;

    @JSONField(ordinal = 3)
    private String sex;

    @JSONField(ordinal = 1)
    private Integer age;
}
//序列化结果:name变为userName
{"age":20,"userName":"zhangsan","sex":"男"}
  •  format
@Data
public class User {
    @JSONField(ordinal = 2 , name="userName")
    private String name;

    @JSONField(ordinal = 3 , format = "yyyy-MM-dd HH:mm:ss")
    private Date birthDay;

    @JSONField(ordinal = 1)
    private Integer age;
}
//序列化结果:
{"age":20,"userName":"zhangsan","birthDay":"2018-11-05 18:26:46"}
  •  serialize

    默认情况下,是true,也就是所有字段都会被序列化。

@Data
public class User {
    @JSONField(ordinal = 2 , name="userName")
    private String name;

    @JSONField(ordinal = 3 , format = "yyyy-MM-dd HH:mm:ss")
    private Date birthDay;

    @JSONField(ordinal = 1 , serialize = false)
    private Integer age;
}
//序列化结果:age没有被序列化
{"userName":"zhangsan","birthDay":"2018-11-05 18:29:19"}
  • deserialize
@Data
public class User {
    @JSONField(ordinal = 2 , name="userName")
    private String name;

    @JSONField(ordinal = 3 , format = "yyyy-MM-dd HH:mm:ss")
    private Date birthDay;

    @JSONField(ordinal = 1 , serialize = false)
    private Integer age;
}

@Test
    public void deserialize(){
        String str = "{\"age\":20,\"userName\":\"zhangsan\",\"birthDay\":\"2018-11-05 18:26:46\"}";
        User user = JSON.parseObject(str, User.class);
        System.out.println(user);
    }

//反序列化结果:
User(name=zhangsan, birthDay=Mon Nov 05 18:26:46 CST 2018, age=20)
  •  serialzeFreature

默认的序列化规则是当你的字段的值为null的时候,它是不会给你序列化这个字段的。我们可以通过serialzeFeatures的属性值SerializerFeature.WriteMapNullValue来控制,当属性的值为null时也输出该字段,字段的值为null。

@Data
public class User {
    @JSONField(ordinal = 2 , name="userName")
    private String name;

    @JSONField(ordinal = 3 , format = "yyyy-MM-dd HH:mm:ss" , serialzeFeatures = SerializerFeature.WriteMapNullValue)
    private Date birthDay;

    @JSONField(ordinal = 1 , serialize = false)
    private Integer age;
}

//JSON.toJSONString(user)序列化的结果:
{"userName":"zhangsan","birthDay":null}

//也可以如下使用,不在字段上做限制。这种情况针对所有字段。
@Test
public void test(){
     User user = initUser();
     String jsonStr = JSON.toJSONString(user , SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullNumberAsZero);
     System.out.println(jsonStr);
}
//输出结果:
{"age":0,"userName":"zhangsan","birthDay":null}

 当然SerializerFeature类中还有很多其他的属性:

名称含义
QuoteFieldNames输出key时是否使用双引号,默认为true
UseSingleQuotes使用单引号而不是双引号,默认为false
WriteMapNullValue是否输出值为null的字段,默认为false
WriteEnumUsingToStringEnum输出name()或者original,默认为false
UseISO8601DateFormatDate使用ISO8601格式输出,默认为false
WriteNullListAsEmptyList字段如果为null,输出为[],而非null
WriteNullStringAsEmpty字符类型字段如果为null,输出为”“,而非null
WriteNullNumberAsZero数值字段如果为null,输出为0,而非null
  • parseFeatures 

    略............

  • jsonDirect
@Data
public class Group {
    private String name;
    @JSONField(jsonDirect = true)
    private String userDetail;
}
@Data
public class User {
    @JSONField(ordinal = 2 , name="userName")
    private String name;

    @JSONField(ordinal = 3 , format = "yyyy-MM-dd HH:mm:ss")
    private Date birthDay;

    @JSONField(ordinal = 1 )
    private Integer age;
}
//测试
    @Test
    public void jsonDirect(){
        User user = new User();
        user.setName("zhangsan");
        user.setBirthDay(new Date());
        user.setAge(10);
        String userJSON = JSON.toJSONString(user);
        Group group = new Group();
        group.setName("1组");
        group.setUserDetail(userJSON);
        String grouJson = JSON.toJSONString(group);
        System.out.println(grouJson);
    }
//输出结果:
{"name":"1组","userDetail":{"birthDay":"2018-11-05 19:16:18","userName":"zhangsan","age":10}}
//而不是:
{"name":"1组","userDetail":"{\"age\":10,\"userName\":\"zhangsan\",\"birthDay\":\"2018-11-05 19:18:33\"}"}
  •  serializeUsing

    如果实体类某字段是String类型,但第三方的相同字段是Interger类型,那么,就需要我们传过去的JSON串中该字段作为key对应的值不可以带双引号。这种情况,也可以用此方法解决。

//实体类
@Data
public class User {
    @JSONField(ordinal = 2 , name="userName")
    private String name;

    @JSONField(ordinal = 3 , format = "yyyy-MM-dd HH:mm:ss")
    private Date birthDay;

    @JSONField(ordinal = 1 , serializeUsing = ModelValueSerializer.class)
    private Integer age;
}

//工具类---需要实现ObjectSerializer重写write方法
public class ModelValueSerializer implements ObjectSerializer {
    @Override
    public void write(JSONSerializer jsonSerializer, Object o, Object o1, Type type, int i) throws IOException {
        Integer value = (Integer) o;
        String text = value + "岁";
        jsonSerializer.write(text);
    }
}

//测试
    @Test
    public void test(){
        User user = new User();
        user.setName("zhangsan");
        user.setBirthDay(new Date());
        user.setAge(10);
        String jsonStr = JSON.toJSONString(user);
        System.out.println(jsonStr);
    }
//结果:
{"age":"10岁","userName":"zhangsan","birthDay":"2018-11-05 19:26:24"}
  • deserializeUsing

     略.........................

  • alternateNames
@Data
public class User {
    @JSONField(ordinal = 2 , name="userName" ,alternateNames = {"userName","studentName"})
    private String name;

    @JSONField(ordinal = 3 , format = "yyyy-MM-dd HH:mm:ss")
    private Date birthDay;

    @JSONField(ordinal = 1 , serializeUsing = ModelValueSerializer.class)
    private Integer age;
}

   @Test
    public void alternateNames(){
        String jsonVal0 = "{\"age\":"10",\"name\":\"zhangsan\",\"birthDay\":\"2018-11-05 19:41:47\"}";
        String jsonVal1 = "{\"age\":11,\"userName\":\"lisi\",\"birthDay\":\"2018-11-05 19:41:47\"}";
        String jsonVal2 = "{\"age\":12,\"studentName\":\"wangwu\",\"birthDay\":\"2018-11-05 19:41:47\"}";

        User obj0 = JSON.parseObject(jsonVal0, User.class);
        System.out.println(obj0);
        User obj1 = JSON.parseObject(jsonVal1, User.class);
        System.out.println(obj1);
        User obj2 = JSON.parseObject(jsonVal2, User.class);
        System.out.println(obj2);
    }

//输出结果:
User(name=null, birthDay=Mon Nov 05 19:41:47 CST 2018, age=10)
User(name=lisi, birthDay=Mon Nov 05 19:41:47 CST 2018, age=11)
User(name=wangwu, birthDay=Mon Nov 05 19:41:47 CST 2018, age=12)

 发现,JSON串中如果是name的话,反序列化的话会是null。但如果是userName或者studentName的话,则会成功反序列化。

 并且,JSON串中age的值是带引号的"10",也就是String类型,而User类中age是Interger类型,这样也可以反序列化成功。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值