使用fastjson的filter机制将String属性转成复杂类型

今天遇到一个很棘手的问题,由于前期设计的失误,导致了数据库中的一个字段不得不用json存储一个非常复杂的对象,前端获取到复杂对象后利用json序列化成jsonstring后存到db中的字段

获取数据的时候从db中取得该jsonstring字段后反序列化成这个复杂对象后传给前端,但是由于这个复杂对象本身利用了list的泛型机制,这样就导致了db中是一个json array并且用一个string存,前端对象是一个list对象,这样反序列化的时候就就不能正确反序列化,因为他试图将一个“[{},{}]”这样的一个格式的内容转成list<>。我先后试过Fastjson,Gson和jackson都不能很好转换

先把之前失败的代码贴一下,相关逻辑已经简化,PO表示数据库持久话对象,BO表示前端展示对象,其中有一个List的复杂对象


class User{
    private String name;
    private String empid;

    public String getName() {
        return name;
    }

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

    public String getEmpid() {
        return empid;
    }

    public void setEmpid(String empid) {
        this.empid = empid;
    }
}

class GroupBO{
    private String groupname;
    private List<User> users;

    public String getGroupname() {
        return groupname;
    }

    public void setGroupname(String groupname) {
        this.groupname = groupname;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

class GroupPO {
    private String groupname;
    private String users;

    public String getGroupname() {
        return groupname;
    }

    public void setGroupname(String groupname) {
        this.groupname = groupname;
    }

    public String getUsers() {
        return users;
    }

    public void setUsers(String users) {
        this.users = users;
    }
}

 

写一个main函数测试一下

public static void main(String[] args) throws IOException {
        //构建VO
        List<User> users=new ArrayList<User>();
        for(int i=0;i<3;i++){
            User u=new User();
            u.setName("name"+i);
            u.setEmpid(String.valueOf(i));
            users.add(u);
        }
        GroupBO groupBO=new GroupBO();
        groupBO.setGroupname("bo_group");
        groupBO.setUsers(users);
        String bojson=JSON.toJSONString(groupBO);
        GroupPO groupPOFromJsonString=JSON.parseObject(bojson,GroupPO.class);
        //构建PO
        GroupPO groupPO=new GroupPO();
        groupPO.setGroupname("po_group");
        groupPO.setUsers("[{\"empid\":\"0\",\"name\":\"name0\"},{\"empid\":\"1\",\"name\":\"name1\"},{\"empid\":\"2\",\"name\":\"name2\"}]");
        String pojson=JSON.toJSONString(groupPO);
        GroupBO groupBOFromJsonString=JSON.parseObject(pojson,GroupBO.class);
        System.out.println("end");
    }

第一步 将一个BO对象序列化成jsonstring,其中的list对象转成一个jsonstring 并存到DB中这部都是没有问题的

GroupPO groupPOFromJsonString=JSON.parseObject(bojson,GroupPO.class);

相应的json格式为

{"groupname":"bo_group","users":[{"empid":"0","name":"name0"},{"empid":"1","name":"name1"},{"empid":"2","name":"name2"}]}

第二步,将一个PO对象(从db中取出)序列化成jsonstring,其中的复杂对象是一个jsonarray的字符串,然后反序列化成一个BO对象,这时候就不行了

GroupBO groupBOFromJsonString=JSON.parseObject(pojson,GroupBO.class);

其中json为

{"groupname":"po_group","users":"[{\"empid\":\"0\",\"name\":\"name0\"},{\"empid\":\"1\",\"name\":\"name1\"},{\"empid\":\"2\",\"name\":\"name2\"}]"}

报错也很直白

com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 32, fastjson-version 1.2.44

这时候就要想办法把其中json的user部分由一个字符串包起来的jsonarray转成一个标准的json array

所以这时候就要利用上fastjson中提供一个filter机制在转jsonstring的时候额外处理一下,对于fastjson来说有几个标准的filter,你可以基于其中filter实现自己的filter 参考 https://github.com/alibaba/fastjson/wiki/SerializeFilter

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

由于是POtoBO的时候,PO中的jsonstirng的value部分序列化不对,所以我们可以定制一个简单的valuefilter来处理对应的jsonstring

class MyToBOFilter implements ValueFilter {
    @Override
    public Object process(Object object, String propertyName, Object propertyValue) {
        try {
            if(propertyName.equals(GroupPO.class.getDeclaredField("users").getName())){
                return JSON.parse(String.valueOf(propertyValue));
            }else{
                return propertyValue;
            }
        } catch (NoSuchFieldException e) {
            return propertyValue;
        }
    }
}

那么在处理POjson的时候调用对应的定制valuefilter

public static void main(String[] args) throws IOException {
    //构建VO
    List<User> users=new ArrayList<User>();
    for(int i=0;i<3;i++){
        User u=new User();
        u.setName("name"+i);
        u.setEmpid(String.valueOf(i));
        users.add(u);
    }
    GroupBO groupBO=new GroupBO();
    groupBO.setGroupname("bo_group");
    groupBO.setUsers(users);
    String bojson=JSON.toJSONString(groupBO);
    GroupPO groupPOFromJsonString=JSON.parseObject(bojson,GroupPO.class);
    //构建PO
    GroupPO groupPO=new GroupPO();
    groupPO.setGroupname("po_group");
    groupPO.setUsers("[{\"empid\":\"0\",\"name\":\"name0\"},{\"empid\":\"1\",\"name\":\"name1\"},{\"empid\":\"2\",\"name\":\"name2\"}]");
    String pojson=JSON.toJSONString(groupPO,new MyToPOFilter());
    GroupBO groupBOFromJsonString=JSON.parseObject(pojson,GroupBO.class);
    System.out.println("end");
}

这时候返回的json为,并且json也可以争取的反序列化成对应的对象了

{"groupname":"po_group","users":[{"empid":"0","name":"name0"},{"empid":"1","name":"name1"},{"empid":"2","name":"name2"}]}

当然在BO转PO的时候你也可以定制自己的valuefilter实现某些前端类型对应DB的字段的逻辑

另外在定制序列化的时候也可以使用pasreprocess来定制,具体可以参考 https://github.com/alibaba/fastjson/wiki/%E5%AE%9A%E5%88%B6%E5%BA%8F%E5%88%97%E5%8C%96

https://github.com/alibaba/fastjson/wiki/ParseProcess

 

转载于:https://my.oschina.net/zimingforever/blog/1611749

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值