json格式化属性自定义-2

时间:2023-01-01 17:16:44

概述:

在Java web开发中免不了要将Java对象格式化成json数据形式返回到客户端,而提供格式化功能的工具也很多,其中以fastjson速度最快。


但是fastjson在使用中显得还不够那么尽人意,

1. 没有提供一个方便点方法来实现过滤属性;

2. 没有提供多条格式化数据整合在一起,而以一个key来对其关联。


一个po对象User如下定义

   public class User {        private int id;
        private String name;
        private String ip;
        private int age;
   }


   而此时如果只想格式化其中的id和ip两个属性,那么怎么办?

   

   格式化的数据大概是:

{"id":xxx,"ip":"xxx"}


   如果想要对这个对象加个key呢?比如是:

   {"user1":{"id":xxx,"ip":"xxx"}}

   加一个key可以通过,将一个user对象保存在一个map对象中,然后对map对象格式得到,那么怎么过滤属性呢?

   又假如此时想格式化两个user对象,其中一个只格式化id,另一个则格式化age和name,那么怎么办?

   格式化的数据大概是:{"user1":{"id":xxx},"user2":{"age":xxx,"name":"xxx"}}

   这个也可以通过一个map中设置多个值达到效果,如:

   Map<String, User> map = new HashMap<String, User>();   map.put("user1", new User());   map.put("user2", new User());


   然后对这个map进行格式化即可得到上面的效果。

   可是不能对第一个user只格式化id,而第二个user只格式化age和name。


   这些原生的fastjson都没有提供好的解决方案。

   过滤属性是的确是提供了方法,如:

PropertyFilter filter = new PropertyFilter() {    public boolean apply(Object source, String propertyName, Object value) {        if (source instanceof Map) {            Class<? extends Object> clazz = value.getClass();            Field[] fields = clazz.getDeclaredFields();            for (Field field : fields) {            String fieldname = field.getName();            for (String name : propertyNames) {                if (name.equals(fieldname)) {                    return keeped;                }            }            return true;        }    } else {        for (String name : propertyNames) {            if (name.equals(propertyName)) {                return keeped;            }        }        return !keeped;    }        return true;    }};    SerializeWriter writer = new SerializeWriter();    JSONSerializer serializer = new JSONSerializer(writer);    serializer.getPropertyFilters().add(filter);    serializer.write(object);    return writer.toString();

然而如果每次过滤属性的时候都去写这样的代码,想必一定是十分的累人。因而可不可以对进行一定的封装而得到一个好用的方法呢?


假如有这样一个方法:

toJSON(final Object object, final boolean keeped, final String... propertyNames)

object:需要格式化的任意对象

keeped:属性格式化还是不格式化的一个标志,true:表示格式化;false:表示不格式化。

propertyNames:自定以的属性名称列表。

当调用这个方法即可自定义属性格式化。


如果这个方法可以是实现,那么自定义属性格式化在编程上将变得简单。


不过以上方法不能很好的实现,

{"user1":{"id":xxx},"user2":{"age":xxx,"name":"xxx"}}

这种类型的格式化。

那么以是否可以提供一个这样的方法:

element(String key, final Object object, final boolean keeped, final String... propertyNames)

key:表示上面的"user1"或者"user2"


如果这个方法也得意实现,那么自定义属性格式化在编程上变得灵活自在。


在附件中已经实现了这样的封装,名称为fastjson_uper_1.0.jar其意是对fastjson的一个更加方便的使用包。在jar包中已经包含了fastjson.jar所以在使用的时候无须再关联。


里面只有一个核心类JSONUtil

它直接继承自JSONObject类,所以fastjson原生的方法,都可以通过JSONUtil来使用。

其中提供了上面提到的方便的,灵活的,对属性自定义格式的方法toJSON,还有element。


toJSON是一个静态方法,可以直接使用。

而element需要创建一个JSONUtil对象才能使用。

element的功能更加强大,因为它可以实现{"user1":{"id":xxx},"user2":{"age":xxx,"name":"xxx"}}这样的格式化操作。

比如:

   

    JSONUtil jsonUtil = new JSONUtil();    jsonUtil.element("user", user, true, "ip");    jsonUtil.element("userList", list, false, "ip", "pwd");    jsonUtil.element("maps", map, true, "ip", "pwd");    jsonUtil.element("set", set, true, "ip");    jsonUtil.element("maps1", subUserMap, true, "ip", "pwd");    jsonUtil.element("user4", user);    System.out.println(jsonUtil.toString());

最后调用toString方法即可得到格式化好的json数据。



在上一篇博客的附件中有json-lib和fastjson灵活格式化的源码,当然fastjson那块不完整。而在本片博客附件中对fastjson的封装是完整的。jar中包含了源代码。