今天遇到一個很棘手的問題,因爲前期設計的失誤,致使了數據庫中的一個字段不得不用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