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

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

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

谢谢,

您必须定义严格的格式并使用解析器跟随它。 有两种可接受的格式:

  • XML – 您可以使用java.beans.XMLEncoder
  • JSON – 使用Jackson或gson

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

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

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

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

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

 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。

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

我正在使用这种toString格式:

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

这是class级:

 public class FromStringBuilder { /** * Parses a string formatted with toStringBuilder * * @param input - ex. "Path[id=1039916,displayName=School Home,description=,...]" * @return hashmap of name value pairs - ex. id=1039916,... */ public static Map stringToMap(String input) { LinkedHashMap ret = new LinkedHashMap(); String partsString = StringUtils.substringBetween(input, "[", "]"); String[] parts = partsString.split(","); for (String part:parts) { String[] nv = part.split("="); if (!StringUtils.equals("", nv[1])) { ret.put(nv[0], nv[1]); } } return ret; } public static  T stringToObject(String input, Class clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException { Map map = stringToMap(input); T ret = clazz.newInstance(); BeanUtils.copyProperties(ret, map); return ret; } } 

XStream库是完美的库

以下是使用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应该与任何其他类似的基于reflection的 Object < - > Text序列化框架一样快,但我没有基准数据。

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