lundi 8 février 2021

Deserialize Java objects by type and fields

I wrote a working method that serializes objects. Standard object serialization from Java does not suit me because of its sensitivity to object changes (static final long serialVersionUID = 1L; do not suggest)))) And I have problems with deserialization ...

    public static <T> String serializeToString(T obj) throws IllegalAccessException {
        String res = "";

        Class<T> type = (Class<T>) obj.getClass();

        res += "Object<" + type.getCanonicalName() + ">" + ":" + "{" + "\n";

        for (Field field : type.getDeclaredFields()) {
            String fieldName = field.getName();

            Object tmpObj = field.get(obj);
            String fieldValue = "";

            if (tmpObj != null) {
                String fullClassName = tmpObj.getClass().getCanonicalName();
                String fieldClass = tmpObj.getClass().getSimpleName();
                
                switch (fieldClass) {
                    case "GregorianCalendar":
                        
                    case "Calendar":
                        fieldValue = calendarToStr((Calendar) tmpObj);
                        break;
                    case "ArrayList":
                        String itemClass = ((ArrayList) tmpObj).get(0).getClass().getCanonicalName();
                        fieldClass = "ArrayList" + "<" + itemClass + ">";
                        fieldValue += "{\n";
                        for (int i = 0; i < ((ArrayList) tmpObj).size(); ++i) {
                            fieldValue += serializeToString(((ArrayList) tmpObj).get(i));
                        }
                        fieldValue += "}";
                        break;
                    case "String":
                        fieldValue = '"' + tmpObj.toString() + '"';
                        fieldClass = fullClassName;
                        break;
                    default:
                        fieldValue = field.get(obj).toString();
                        fieldClass = fullClassName;
                        break;
                }
                res += fieldClass + ":" + fieldName + ":" + fieldValue + "\n";
            }
        }
        res += "}" + "\n";

        return res;
    }

This method serializes objects into the following form:

Object<com.user.myproject.Day>:{
GregorianCalendar:date:01-02-2021
java.lang.Integer:id:0
ArrayList<com.user.myproject.Line>:lineList:{
Object<com.user.myproject.Line>:{
java.lang.Integer:color:-16776961
java.lang.Integer:id:0
java.lang.String:name:"Line 0"
ArrayList<com.user.myproject.Point>:stack:{
Object<com.user.myproject.Point>:{
java.lang.Boolean:auxiliary:false
java.lang.Integer:color:-16776961
java.lang.String:desc:""
java.lang.Integer:id:0
java.lang.Boolean:interpolated:false
java.lang.Integer:lineID:0
java.lang.String:marker:"0"
java.lang.Integer:ref:-1
java.lang.Double:x:0.0
java.lang.Double:y:0.0
}
Object<com.user.myproject.Point>:{
java.lang.Boolean:auxiliary:false
java.lang.Integer:color:-16776961
java.lang.String:desc:"Point 2"
java.lang.Integer:id:1
java.lang.Boolean:interpolated:false
java.lang.Integer:lineID:0
java.lang.String:marker:"1"
java.lang.Integer:ref:-1
java.lang.Double:x:12.383333333333333
java.lang.Double:y:6.0
}
}
}
}
}

I need to restore objects from this text.

Here is the method I managed to write. Unfortunately, it doesn't work as expected.

public static deserializerData deserializeFromString(String str) {
        String[] rows = str.split("\n");

        deserializerData res = new deserializerData("ERROR", "ERROR");
        
        for (int i = 0; i < rows.length; ++i) {
            String[] rowsplitted = rows[i].split(":", 3);
            String type;
            String fieldName;
            String value;
            type = rowsplitted[0];
            if (rowsplitted.length == 3) {
                fieldName = rowsplitted[1];
                value = rowsplitted[2];
                if (type.contains("Calendar") || type.contains("GregorianCalendar")) {
                    res = new deserializerData(fieldName, calendarFromString(value), type);
                } else {
                    res = new deserializerData(fieldName, String.valueOf(value), type);
                }
            } else if (type.contains("Object")) {
                String objectClass = type.split("<")[1].substring(0, type.split("<")[1].length() - 1);
                String objClassName = objectClass.split("\\.")[objectClass.length() - 1];
                ArrayList<deserializerData> args = new ArrayList<>();
                int j = i;
                String curRow = rows[i];
                while (!curRow.equals("}")) {
                    ++j;
                    curRow = rows[j];
                    args.add(deserializeFromString(curRow));

                }
                i = j + 1;
                Object obj = null;
                try {
                    obj = Class.forName(objClassName).newInstance();
                    for (int k = 0; k < args.size(); k++) {
                        Field field = obj.getClass().getField(args.get(i).getFieldName());
                        field.set(obj, args.get(i).getObj());
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
                res = new deserializerData("Deserialized", obj);
            } else if(type.contains("ArrayList")){
                String arrayClass = type.split("<")[1].substring(0, type.split("<")[1].length() - 1);

            }
        }

//            if(type.contains("ArrayList")){
//                String arrayClass = type.split("<")[1].substring(0,type.split(">")[1].length()-1);
//                ArrayList list = new ArrayList();
//                int j = i;
//                String curRow = rows[i];
//                while(!curRow.equals("}")){
//                    list.add(deserializeFromString(deserializeFromString(curRow)));
//                    ++j;
//                    curRow=rows[j];
//                }
//                return list;
//            }else{
//                Object obj = new Object();
//            }
//        }
//        return new Object();
        return res;
    }




Aucun commentaire:

Enregistrer un commentaire