Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse ToStringBuilder : convert string to object

Tags:

java

Is there a way to convert my output from ToStringBuilder back to java object?

I am looking for an easy way to represent a Java object in readable text file and being able to convert back and forth between string and object.

Thanks,

like image 959
Sean Nguyen Avatar asked Dec 03 '10 08:12

Sean Nguyen


3 Answers

You must define a strict format and follow it with a parser. There are two accepted formats:

  • XML - you can use java.beans.XMLEncoder
  • JSON - use Jackson or gson

If you don't choose these formats you will have to handle the parsing yourself.

The ToStringBuilder does not seem to have a reverse equivalent. Furthermore it is wrong to use this string representation for such purposes - it is meant only for debug.

like image 134
Bozho Avatar answered Nov 04 '22 12:11

Bozho


You'll have to parse your string representation of the object and then construct a new object initialised with those values.

If you want to keep it generic and have it work for any object type, you can use Apache BeanUtils to help.

For example, if your string representation is:

Person@7f54[name=Stephen,age=29,smoker=false]

Parse out the class name, fields and values. Then use BeanUtils to construct a new Person:

String className = "Person";
Class beanClass = Class.forName(className);
Person myPerson = (Person)beanClass.newInstance();
BeanUtils.setProperty(myPerson, "name", "Stephen");
BeanUtils.setProperty(myPerson, "age", "29");
BeanUtils.setProperty(myPerson, "smoker", "false");

This assumes that your Person class is a bean and exposes getters/setters for its fields.

like image 22
dogbane Avatar answered Nov 04 '22 11:11

dogbane


Sean, I came across your question while looking for a simple test case converter based on a reflection-based String output of an object. While a more robust library for json or XML is certainly important for a wide range of input, this is handy for quick and dirty test cases. It handles simple, non-nested POJOs. Its only dependency is apache commons.

I'm using this toString format:

@Override
public String toString() {
    return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}

Here is the class:

public class FromStringBuilder {

/**
 * Parses a string formatted with toStringBuilder
 * 
 * @param input - ex. "Path[id=1039916,displayName=School Home,description=<null>,...]"
 * @return hashmap of name value pairs - ex. id=1039916,... 
 */
public static Map<String, String> stringToMap(String input) {
    LinkedHashMap<String, String> ret = new LinkedHashMap<String, String>();
    String partsString = StringUtils.substringBetween(input, "[", "]");
    String[] parts = partsString.split(",");
    for (String part:parts) {
        String[] nv = part.split("=");
        if (!StringUtils.equals("<null>", nv[1])) {
            ret.put(nv[0], nv[1]);
        }
    }
    return ret;
}

public static <T> T stringToObject(String input, Class<T> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException {
    Map<String, String> map = stringToMap(input);
    T ret = clazz.newInstance();
    BeanUtils.copyProperties(ret, map);
    return ret;
}
}
like image 41
ledlogic Avatar answered Nov 04 '22 10:11

ledlogic