反向ToStringBuilder:将字符串转换为对象

时间:2010-12-03 08:53:40

标签: java

有没有办法将我的输出从ToStringBuilder转换回java对象?

我正在寻找一种简单的方法来在可读文本文件中表示Java对象,并能够在字符串和对象之间来回转换。

谢谢,

5 个答案:

答案 0 :(得分:2)

您必须定义严格格式并使用解析器进行操作。有两种可接受的格式:

如果您不选择这些格式,则必须自己处理解析。

ToStringBuilder似乎没有反向等价物。此外,为此目的使用此字符串表示是错误的 - 它仅用于调试。

答案 1 :(得分:1)

您必须解析对象的字符串表示形式,然后构造一个使用这些值初始化的新对象。

如果您希望保持通用并使其适用于任何对象类型,您可以使用Apache BeanUtils来提供帮助。

例如,如果您的字符串表示为:

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

解析类名,字段和值。然后使用BeanUtils构造一个新的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");

这假设您的Person类是一个bean,并为其字段公开getter / setter。

答案 2 :(得分:1)

Sean,我在寻找一个基于对象的基于反射的String输出的简单测试用例转换器时遇到了你的问题。虽然json或XML的更强大的库对于广泛的输入肯定是重要的,但这对于快速和脏的测试用例来说非常方便。它处理简单的非嵌套POJO。它唯一的依赖是apache commons。

我使用这种toString格式:

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

这是班级:

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;
}
}

答案 3 :(得分:0)

XStream库是最完美的

答案 4 :(得分:0)

以下是使用Gson的示例:

public class GsonTest {
    static class Name { String first; String last; }
    static class Data { int number; Name name = new Name(); }

    public static void main(String[] args) {
        Gson gson = new Gson();

        Data data1 = new Data();
        data1.number = 1;
        data1.name.first = "Joe";
        data1.name.last = "Smith";
        print("data1", data1);

        String jsonString = gson.toJson(data1);
        System.out.println("jsonString: " + jsonString);

        Data data2 = gson.fromJson(jsonString, Data.class);
        print("data2", data2);
    }

    private static void print(String id, Data data) {
        System.out.println(id + "     :" 
                + " number=" + data.number 
                + " name.first=" + data.name.first
                + " name.last=" + data.name.last);
    }
}

<强>输出

data1     : number=1 name.first=Joe name.last=Smith
jsonString: {"number":1,"name":{"first":"Joe","last":"Smith"}}
data2     : number=1 name.first=Joe name.last=Smith

<强>速度

Gson应该与其他任何类似的基于反射的对象&lt; - &gt;文本序列化框架一样快,但我没有基准数据。

Bean支持

与XStream(可选)和java.beans.XMLEncoder / XMLEncoder不同,Gson不使用类的setter和getter方法。相反,它直接读取和写入类的成员字段,类似于Java二进制序列化(ObjectOutputStream等)。虽然Gson应该能够正确地编组和解组大多数JavaBeans,但是必须牢记Gson的这个实现细节并将其解释为

漂亮的JSON输出

默认情况下,GSON在一行上输出JSON,作为优化。它可以输出稍微容易阅读的JSON。通过以稍微不同的方式构造Gson对象来做到这一点:

Gson gson = new GsonBuilder().setPrettyPrinting().create();

JSON输出(继续上面的示例)现在看起来像:

{
  "number": 1,
  "name": {
    "first": "Joe",
    "last": "Smith"
  }
}

而不是

{"number":1,"name":{"first":"Joe","last":"Smith"}}