我需要解析一个文本文件并生成JSON文档。该文本文件有一个文本模式,其中包含一个关键字,这是一个名称和值是一个巨大的文本TSV与头部。
我可以解析文本文件并使用头生成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();
}
3条答案
按热度按时间x33g5p2x1#
我意识到,与其用复杂的方法创建POJO,不如使用
Map
并使用JacksonObjectMapper
将其转换为JSON。68bkxrlz2#
你的解决方案太过火了。
您的数据被组织为可变长度数组的数组;并且不需要一些疯狂的动态类生成解决方案。作为一个旁注,动态类生成本质上并不疯狂;在这种情况下使用动态类生成是疯狂。
请执行以下操作:
1.看看你的数据;其组织结构如下:
1.第一个:外键
1.第二行:正好一行,包含可变数量的空格分隔的内部键数组。
1.第三:一定数量的包含值的行。
1.设计解决方案来解决您的问题
1.读取外键,使用该值创建JSON的外键部分。
1.读取内部键,并将其存储在数组中;使用链接列表,而不是小丑列表(数组列表)。
1.执行此操作,直到下一个空行:
1.读取一行值。
1.编写内部JSON;使用内部密钥作为此操作的密钥。
1.跳过空行,直到出现以下情况之一:
1.如果在文件末尾,则写入JSON的结尾部分。
1.如果你读取下一个外键,转到上面的第2行(读取内键)。
1.编写代码。
kq4fsx7k3#
您不需要编写所有的逻辑,您可以只使用Apache Commons BeanUtils;它提供了一个实用程序方法(在 MANY 个其他实用程序中),该方法采用字段名与字段值的
Map
,并用它填充给定的bean:那么您需要实现的唯一事情就是创建
fieldNameValueMap
x 1 m2n1x的逻辑;你可以用这个简单的方法您可以使用以下工作演示来测试此解决方案:
这是这个依赖项的maven存储库页面,因此您可以将其包含在您的构建中:https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils/1.9.3
我在这个解决方案中也使用了Lombok,只是为了保存编写getter/setters/toString来测试这个解决方案的麻烦;但您的解决方案并不需要它。
Complete code on GitHub