赞
踩
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.21</version>
- </dependency>
PS:这里只陈述第一种方式。
- @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 {};//反序列化时使用多个不同的字段名称
- }
- @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":"男"}
- @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":"男"}
- @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"}
默认情况下,是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"}
- @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)
默认的序列化规则是当你的字段的值为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 |
WriteEnumUsingToString | Enum输出name()或者original,默认为false |
UseISO8601DateFormat | Date使用ISO8601格式输出,默认为false |
WriteNullListAsEmpty | List字段如果为null,输出为[],而非null |
WriteNullStringAsEmpty | 字符类型字段如果为null,输出为”“,而非null |
WriteNullNumberAsZero | 数值字段如果为null,输出为0,而非null |
略............
- @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\"}"}
如果实体类某字段是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"}
略.........................
- @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类型,这样也可以反序列化成功。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。