由于我需要多次使用它,因此我试图为Java中的类的字段自动生成CSV映射。
我有以下尝试获取字段名称的方法:(其中CSV标头类似于“ DB_NAME | FIELD_NAME | ADDITIONAL_F1 | ADDITIONAL_F2”)
package util;
import java.lang.reflect.Field;
public class CsvAttributesMappingGenerator {
public static String generateCsvAttributesMapping(Class<?> model) {
StringBuilder csvBuilder = new StringBuilder();
Field[] fieldList = model.getDeclaredFields();
for (Field field : fieldList) {
//field.setAccessible(true);
csvBuilder.append(field.getName().replaceAll("(.)(\\p{Upper})", "$1_$2").toUpperCase());
csvBuilder.append("|");
csvBuilder.append(field.getName());
csvBuilder.append("||\n");
}
return formatOutput(csvBuilder.toString());
}
private static String formatOutput(String classText) {
String delimiter = "\n******************************\n";
return String.format("%s%s%s", delimiter, classText, delimiter);
}
}
和一个类似的测试电话:
import objects.User;
import org.junit.Test;
import util.CsvAttributesMappingGenerator;
public class CsvAttributesMappingGeneratorTest {
@Test
public void testGenerationWithObject() {
System.out.println(CsvAttributesMappingGenerator.generateCsvAttributesMapping(User.class));
}
}
要解析的对象具有以下结构: 包对象;
public class User {
private String userName;
private String userEmail;
private int userAge;
private String otherDetails;
// getters, setters and all args constuctor here
}
输出应具有多行,例如FIELD_NAME | fieldName ||应从给定班级收集骆驼装箱的物品。正如我在几个示例中看到的那样,我尝试使用Java Reflection API,但是却得到了奇怪的String输出。 (而不是序列化的@randomCharsLikeName)。尝试了toString()和其他肮脏的技巧,但没有任何效果。
有人可以给我这个小费吗?或者至少告诉我是否可以做我尝试过的事情? 预先感谢!
编辑:问题中介绍的当前代码原型在隔离的环境(单独的新项目)中运行,并显示预期的输出。尽管集成到了我要集成到的整个应用程序中,但它不起作用。我将继续研究,并让您知道根本原因(在真实的应用中,我还将lombok用于课程(
@ AllArgsConstructor,@ NoArgsConstructor,@ Data,@ ToString
),但老实说,我不认为这可能是使用反射的问题)
答案 0 :(得分:0)
与此同时,我发现了这个问题。在对生成器进行播放原型制作时,我使用了:
csvBuilder.append(field.getClass().getName().replaceAll("(.)(\\p{Upper})", "$1_$2").toUpperCase());
产生了类似JAVA.LANG.REFLECT._FIELD|java.lang.reflect.Field||
由于我只是忘记了我实际上对其进行了改进,以使用实际的类对象作为函数的参数。在问问题之前,我对代码进行了一些Sonar修复,但没有注意到我修复了WARN以删除.getClass()
方法调用,因为我已经传递了一个类(我认为这样做没有什么区别。只是警告)。 每日道德提示-永远不要忽略警告。
因此,问题中显示的代码段现在可以在一个隔离的虚拟项目中正常工作,并且还可以使用固定的行集成到一个更复杂的项目中:
csvBuilder.append(field.getName().replaceAll("(.)(\\p{Upper})", "$1_$2").toUpperCase());
正如评论中的建议一样,field.setAccessible(true);
也可以删除,因为它对于该方法没有用。