我需要解析一个文本文件并生成 JSON 文档。文本文件有一个文本模式,其中包含一个键,它是一个名称,值是一个带有标题的巨大 TSV 文本。
我可以解析文本文件并使用 header 生成 bean 类,现在我想将数据设置到这个生成的 bean 类。我正在使用反射来执行此操作。
Class<?> beanClass = BeanClassGenerator.beanGenerator(k, mapForBeanGeneration);
try {
Object beanClassObject = beanClass.newInstance();
lines.forEach(line -> {
if (line != null && !line.isEmpty() && !line.equals("null")) {
String[] lineData = line.split("\t");
System.out.println("LineData length :: " + lineData.length);
Method[] methods = beanClass.getMethods();
System.out.println("Methods length :: " + methods.length);
int index = 0;
for (Method m : methods) {
m.setAccessible(true);
if (m.getName().startsWith("set")) {
try {
if ((lineData.length <= index) && lineData[index] != null) {
m.invoke(beanClassObject, lineData[index]);
index++;
} else {
m.invoke(beanClassObject, " ");
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
});
ObjectMapper om = new ObjectMapper();
System.out.println(om.writeValueAsString(beanClassObject));
} catch (InstantiationException | IllegalAccessException | JsonProcessingException e) {
e.printStackTrace();
}});
该方法的问题在于,大多数时候所有列值可能都没有数据,因此可以将其置空。
我想知道是否有更简单的方法来做到这一点。感谢您的帮助。
这里是bean的生成方法。
public static Class<?> beanGenerator(final String className, final Map<String, Class<?>> properties) {
BeanGenerator beanGenerator = new BeanGenerator();
beanGenerator.setNamingPolicy(new NamingPolicy() {
@Override
public String getClassName(String prefix, String source, Object key, Predicate names) {
return className;
}
});
BeanGenerator.addProperties(beanGenerator, properties);
return (Class<?>) beanGenerator.createClass();
}
这是需要转换为 JSON 输出的示例文本文件。
<Data1>
Col1 col2 col3 col4 col5
even sense met has
root greatest spin mostly
gentle held introduced palace
cold equator remember grandmother
slightly butter depth like
distant second coast everyone
<Data2>
Col1 col2 col3 col4 col5 col6 col7 col8
greatest rope operation flies brown continent combination read
slightly diagram he grandfather where party fifty pour
well put plastic anyway refer careful correct furniture
how since army tongue birthday been clock official
table command specific distant cutting hill movie experience
national though stopped youth army underline five know
<Data3>
Col1 col2 col3 col4 col5 col6 col7 col8 col9 col9 col10
vessels characteristic ship joy than tomorrow high seven future trade
try gray fourth advice week stream motion musical whom tin
limited daughter large rice came home chicken wheat engine box
easy city pair strange stage visitor coach announced allow simple
jet therefore single during construction flag bigger muscle complex pleasure
income several coat range dull cattle damage jump present shake
JSON 输出:
[{
"<Data1>": [{
"col1": "",
"col2": "",
"col3": "",
"col4": ""
},
{
"col1": "",
"col2": "",
"col3": "",
"col4": ""
},
{
"col1": "",
"col2": "",
"col3": "",
"col4": ""
}
]
}, {
"<Data2>": [{
"col1": "",
"col2": "",
"col3": "",
"col4": "",
"col5": "",
"col6": "",
"col7": "",
"col8": ""
},
{
"col1": "",
"col2": "",
"col3": "",
"col4": "",
"col5": "",
"col6": "",
"col7": "",
"col8": ""
},
{
"col1": "",
"col2": "",
"col3": "",
"col4": "",
"col5": "",
"col6": "",
"col7": "",
"col8": ""
}
]
}]
我想出了一个使用 map 的解决方案。
Map<String, List<Map<String, String>>> finalMap = new HashMap<>();
metadataMap.forEach((k, v) -> {
List<Map<String, String>> datamap = new ArrayList<>();
String key = k;
String[] fields = v.getFields();
List<String> lines = v.getLines();
lines.forEach(line -> {
if (line != null && !line.isEmpty() && !line.equals("null")) {
String[] fieldData = line.split("\t");
Map<String, String> eachLineMap = new HashMap<>();
for (int index = 0; index < fields.length; index++) {
if (index < fieldData.length && (fieldData[index] != null && !fieldData[index].isEmpty())) {
eachLineMap.put(fields[index], fieldData[index]);
} else {
eachLineMap.put(fields[index], " ");
}
datamap.add(eachLineMap);
}
}
});
finalMap.put(key, datamap);
});
try {
output = new ObjectMapper().writeValueAsString(finalMap);
}catch(JsonProcessingException e){
e.printStackTrace();
}
最佳答案
您的解决方案太过分了。
您的数据被组织为可变长度数组的数组;
并且不需要一些疯狂的即时类生成解决方案。
作为旁注,
即时类生成本身并不疯狂;
在这种情况下使用即时类生成是疯狂的。
这样做:
- 查看您的数据;
它的组织如下:
- 第一:外键
- 第二个:恰好一行包含可变数量的空格分隔的内部键数组。
- 第三:一些包含值的行。
- 设计一个解决方案来解决您的问题
- 读取外键。 使用该值创建 JSON 的外键部分。
- 阅读内部按键。 将这些存储在一个数组中; 使用链表, 不是 ClownList (ArrayList)。
- 这样做直到下一个空行:
- 读取一行值。
- 编写内部JSON;使用内部键作为键。
- 跳过空行,直到出现以下情况之一:
- 如果在文件末尾,写入 JSON 的结尾部分。
- 如果您读取下一个外部 key ,请转到上面的第 2 行(读取内部 key )。
- 编写代码。
关于java - 动态创建 POJO/bean 并使用 CGLib 设置值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56261526/