今天遇到一个很棘手的问题,因为前期设计的失误,致使了数据库中的一个字段不得不用json存储一个很是复杂的对象,前端获取到复杂对象后利用json序列化成jsonstring后存到db中的字段前端
获取数据的时候从db中取得该jsonstring字段后反序列化成这个复杂对象后传给前端,可是因为这个复杂对象自己利用了list的泛型机制,这样就致使了db中是一个json array而且用一个string存,前端对象是一个list对象,这样反序列化的时候就就不能正确反序列化,由于他试图将一个“[{},{}]”这样的一个格式的内容转成list<>。我前后试过Fastjson,Gson和jackson都不能很好转换java
先把以前失败的代码贴一下,相关逻辑已经简化,PO表示数据库持久话对象,BO表示前端展现对象,其中有一个List的复杂对象git
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函数测试一下github
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格式为json
{"groupname":"bo_group","users":[{"empid":"0","name":"name0"},{"empid":"1","name":"name1"},{"empid":"2","name":"name2"}]}ide
第二步,将一个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\"}]"}this
报错也很直白
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
因为是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