java - OpenCSV java.lang.NoSuchMethodException:类 Y 上的未知属性“X”
问题描述
我正在尝试从 bean 列表中使用 openCSV 4.6 编写 CSV。但是,每当我运行我的程序时,我都会收到 CsvBeanIntrospectionException,然后是 NoSuchMethodException: Unknown property 'Etrangers' on class 'class Properties' 尝试在类 Properties 中操作 bean 的属性 Etrangers 时引发自省错误。
这是我的对象“geojsonParsing”的代码:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
import com.codebind.Geometry.GeometryType;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.opencsv.CSVWriter;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import com.opencsv.bean.MappingStrategy;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
interface Geometry {
GeometryType getType();
enum GeometryType {
Polygon, MultiPolygon
}
}
class OrderedComparatorIgnoringCase implements Comparator<String> {
private List<String> predefinedOrder;
public OrderedComparatorIgnoringCase(String[] predefinedOrder) {
this.predefinedOrder = new ArrayList<>();
for(String item : predefinedOrder) {
this.predefinedOrder.add(item.toLowerCase());
}
}
@Override
public int compare(String o1, String o2) {
return predefinedOrder.indexOf(o1.toLowerCase()) - predefinedOrder.indexOf(o2.toLowerCase());
}
}
class CsvUtils {
private CsvUtils() {
}
public static <T> String convertToCsv(List<T> entitiesList, MappingStrategy<T> mappingStrategy) throws Exception {
try (Writer writer = new StringWriter()) {
StatefulBeanToCsv<T> beanToCsv = new StatefulBeanToCsvBuilder<T>(writer).withMappingStrategy(mappingStrategy).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).build();
beanToCsv.write(entitiesList);
return writer.toString();
}
}
@SuppressWarnings("unchecked")
public static <T> List<T> convertFromCsv(MultipartFile file, Class clazz) throws IOException {
try (Reader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(reader).withType(clazz).build();
return csvToBean.parse();
}
}
}
class MultiPolygonGeometry implements Geometry {
private final GeometryType type = GeometryType.MultiPolygon;
private double[][][][] coordinates;
public GeometryType getType() {
return type;
}
public double[][][][] getCoordinates() {
return coordinates;
}
public void setCoordinates(double[][][][] coordinates) {
this.coordinates = coordinates;
}
}
class PolygonGeometry implements Geometry {
private final GeometryType type = GeometryType.Polygon;
private double[][][] coordinates;
public GeometryType getType() {
return type;
}
public double[][][] getCoordinates() {
return coordinates;
}
public void setCoordinates(double[][][] coordinates) {
this.coordinates = coordinates;
}
}
class Data {
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Feature> getFeatures() {
return features;
}
public void setFeatures(List<Feature> features) {
this.features = features;
}
private String type;
private List<Feature> features;
}
class Feature {
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Geometry getGeometry() {
return geometry;
}
public void setGeometry(Geometry geometry) {
this.geometry = geometry;
}
private String type;
private Properties properties;
private Geometry geometry;
}
class GeometryDeserializer implements JsonDeserializer<Geometry> {
@Override
public Geometry deserialize(JsonElement json,
java.lang.reflect.Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
GeometryType type = context.deserialize(jsonObject.get("type"), GeometryType.class);
switch(type) {
case Polygon:
return context.deserialize(json, PolygonGeometry.class);
case MultiPolygon:
return context.deserialize(json, MultiPolygonGeometry.class);
default:
throw new JsonParseException("Unrecognized Geometry type: " + type);
}
}
}
// You only need to add/generate getters and s
public class geojsonParsing {
public static void main(String[] args) throws Exception {
GsonBuilder builder = new GsonBuilder();
final Path source = Paths.get(System.getProperty("user.dir") + "/REGIONS.json");
try (final InputStream is = new FileInputStream(source.toFile());
final BufferedInputStream bis = new BufferedInputStream(is);) {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
buf.write((byte) result);
result = bis.read();
}
String jsonstring = buf.toString("UTF-8");
builder.registerTypeAdapter(Geometry.class, new GeometryDeserializer());
Data data = builder.create().fromJson(jsonstring, Data.class);
Writer writer = new FileWriter(System.getProperty("user.dir") + "/REGIONS.csv");
List<Properties> localBusinessTrainingPairsDTO = new ArrayList<>();
for(int i = 0; i < data.getFeatures().size(); i++) {
localBusinessTrainingPairsDTO.add(data.getFeatures().get(i).getProperties());
}
// Creating HeaderColumnNameMappingStrategy
HeaderColumnNameMappingStrategy<Properties> mappingStrategy = new HeaderColumnNameMappingStrategy<Properties>();
mappingStrategy.setType(Properties.class);
// Setting predefined order using String comparator
mappingStrategy.setColumnOrderOnWrite(new OrderedComparatorIgnoringCase(Properties.FIELDS_ORDER));
String csv = CsvUtils.convertToCsv(localBusinessTrainingPairsDTO, mappingStrategy);
System.out.println(csv);
writer.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
import com.opencsv.bean.CsvBindByName;
public class Properties {
public static String[] getFieldsOrder() {
return FIELDS_ORDER;
}
public String getCODE_REGIO() {
return CODE_REGIO;
}
public void setCODE_REGIO(String cODE_REGIO) {
CODE_REGIO = cODE_REGIO;
}
public Integer getPopulation() {
return Population;
}
public void setPopulation(Integer population) {
Population = population;
}
public Integer getMenages() {
return Menages;
}
public void setMenages(Integer menages) {
this.Menages = menages;
}
public Integer getEtrangers() {
return Etrangers;
}
public void setEtrangers(Integer etrangers) {
this.Etrangers = etrangers;
}
public Integer getMarocains() {
return Marocains;
}
public void setMarocains(Integer marocains) {
this.Marocains = marocains;
}
public String getNom_Region() {
return Nom_Region;
}
public void setNom_Region(String nom_Region) {
Nom_Region = nom_Region;
}
public Integer getRuleID() {
return RuleID;
}
public void setRuleID(Integer ruleID) {
RuleID = ruleID;
}
public Double getShape__Are() {
return Shape__Are;
}
public void setShape__Are(Double shape__Are) {
Shape__Are = shape__Are;
}
public Double getShape__Len() {
return Shape__Len;
}
public void setShape__Len(Double shape__Len) {
Shape__Len = shape__Len;
}
@CsvBindByName(column = "CODE_REGIO")
private String CODE_REGIO;
@CsvBindByName(column = "Etrangers")
private Integer Etrangers;
@CsvBindByName(column = "Marocains")
private Integer Marocains;
@CsvBindByName(column = "Menages")
private Integer Menages;
@CsvBindByName(column = "Nom_Region")
private String Nom_Region;
@CsvBindByName(column = "Population")
private Integer Population;
@CsvBindByName(column = "RuleID")
private Integer RuleID;
@CsvBindByName(column = "Shape__Are")
private Double Shape__Are;
@CsvBindByName(column = "Shape__Len")
private Double Shape__Len;
public static final String[] FIELDS_ORDER = { "CODE_REGIO",
"Etrangers",
"Marocains",
"Menages",
"Nom_Region",
"Population",
"RuleID",
"Shape__Are",
"Shape__Len" };
}
而对于 Maven
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
我得到的例外
Exception in thread "pool-1-thread-1" Exception in thread "pool-1-thread-4" Exception in thread "pool-1-thread-3" Exception in thread "pool-1-thread-2" com.opencsv.exceptions.CsvBeanIntrospectionException: An introspection error was thrown while attempting to manipulate property Etrangers of bean com.codebind.Properties.
at com.opencsv.bean.AbstractBeanField.write(AbstractBeanField.java:391)
at com.opencsv.bean.AbstractMappingStrategy.writeWithReflection(AbstractMappingStrategy.java:477)
at com.opencsv.bean.AbstractMappingStrategy.transmuteBean(AbstractMappingStrategy.java:458)
at com.opencsv.bean.concurrent.ProcessCsvBean.run(ProcessCsvBean.java:65)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodException: Unknown property 'Etrangers' on class 'class com.codebind.Properties'
at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1269)
at com.opencsv.bean.AbstractBeanField.write(AbstractBeanField.java:388)
... 6 moreException in thread "pool-1-thread-1" Exception in thread "pool-1-thread-4" Exception in thread "pool-1-thread-3" Exception in thread "pool-1-thread-2" com.opencsv.exceptions.CsvBeanIntrospectionException: An introspection error was thrown while attempting to manipulate property Etrangers of bean com.codebind.Properties.
at com.opencsv.bean.AbstractBeanField.write(AbstractBeanField.java:391)
at com.opencsv.bean.AbstractMappingStrategy.writeWithReflection(AbstractMappingStrategy.java:477)
at com.opencsv.bean.AbstractMappingStrategy.transmuteBean(AbstractMappingStrategy.java:458)
at com.opencsv.bean.concurrent.ProcessCsvBean.run(ProcessCsvBean.java:65)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodException: Unknown property 'Etrangers' on class 'class com.codebind.Properties'
at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1269)
at com.opencsv.bean.AbstractBeanField.write(AbstractBeanField.java:388)
... 6 more
解决方案
我通过使用解决了
import com.opencsv.bean.HeaderColumnNameTranslateMappingStrategy;
代替
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
并使用
import org.apache.commons.collections4.comparators.FixedOrderComparato4r;
`
并通过创建 Hashmap 将 csv 标头数据映射到 Bean 字段属性的大写起始字母。
// Hashmap to map CSV data to
// Bean attributes.
Map<String, String> mapping = new HashMap<String, String>();
mapping.put("code_regio", "CODE_REGIO");
mapping.put("etrangers", "Etrangers");
mapping.put("marocains", "Marocains");
mapping.put("menages", "Menages");
mapping.put("nom_region", "Nom_Region");
mapping.put("population", "Population");
mapping.put("ruleid", "RuleID");
mapping.put("shape__are", "Shape__Are");
mapping.put("shape__len", "Shape__Len");
// Creating HeaderColumnNameMappingStrategy
HeaderColumnNameTranslateMappingStrategy<Properties> mappingStrategy = new HeaderColumnNameTranslateMappingStrategy<Properties>();
mappingStrategy.setType(Properties.class);
mappingStrategy.setColumnMapping(mapping);
// Setting predefined order using String comparator
mappingStrategy.setColumnOrderOnWrite(new FixedOrderComparator<>(Properties.FIELDS_ORDER));
String csv = CsvUtils.convertToCsv(localBusinessTrainingPairsDTO, mappingStrategy);
System.out.println(csv);
writer.close();
在属性类中,我将所有 FIELDS_ORDER 都大写
public static final String[] FIELDS_ORDER = { "CODE_REGIO",
"ETRANGERS",
"MAROCAINS",
"MENAGES",
"NOM_REGION",
"POPULATION",
"RULEID",
"SHAPE__ARE",
"SHAPE__LEN" };
这样映射 bean Properties 类就变成如下所示
import com.opencsv.bean.CsvBindByName;
public class Properties {
public static String[] getFieldsOrder() {
return FIELDS_ORDER;
}
public String getCODE_REGIO() {
return CODE_REGIO;
}
public void setCODE_REGIO(String cODE_REGIO) {
CODE_REGIO = cODE_REGIO;
}
public int getPopulation() {
return Population;
}
public void setPopulation(int population) {
Population = population;
}
public int getMenages() {
return Menages;
}
public void setMenages(int menages) {
Menages = menages;
}
public int getEtrangers() {
return Etrangers;
}
public void setEtrangers(int etrangers) {
Etrangers = etrangers;
}
public int getMarocains() {
return Marocains;
}
public void setMarocains(int marocains) {
Marocains = marocains;
}
public String getNom_Region() {
return Nom_Region;
}
public void setNom_Region(String nom_Region) {
Nom_Region = nom_Region;
}
public int getRuleID() {
return RuleID;
}
public void setRuleID(int ruleID) {
RuleID = ruleID;
}
public double getShape__Are() {
return Shape__Are;
}
public void setShape__Are(double shape__Are) {
Shape__Are = shape__Are;
}
public double getShape__Len() {
return Shape__Len;
}
public void setShape__Len(double shape__Len) {
Shape__Len = shape__Len;
}
@CsvBindByName(column = "CODE_REGIO", required = true)
private String CODE_REGIO;
@CsvBindByName(column = "Etrangers", required = true)
private int Etrangers;
@CsvBindByName(column = "Marocains", required = true)
private int Marocains;
@CsvBindByName(column = "Menages", required = true)
private int Menages;
@CsvBindByName(column = "Nom_Region", required = true)
private String Nom_Region;
@CsvBindByName(column = "Population", required = true)
private int Population;
@CsvBindByName(column = "RuleID", required = true)
private int RuleID;
@CsvBindByName(column = "Shape__Are", required = true)
private double Shape__Are;
@CsvBindByName(column = "Shape__Len", required = true)
private double Shape__Len;
public static final String[] FIELDS_ORDER = { "CODE_REGIO",
"ETRANGERS",
"MAROCAINS",
"MENAGES",
"NOM_REGION",
"POPULATION",
"RULEID",
"SHAPE__ARE",
"SHAPE__LEN" };
}
推荐阅读
- c# - 如何最好地在 .Net Core 中加密/解密非常大的文件
- javascript - 如何从 JSON URL 获取特定数据并使用 Typeahead.js 将其用于我的过滤器搜索?
- airflow - 气流中相同 DAG 的多个实例在没有任何日志的情况下失败
- php - 为什么 Laravel 项目显示 502 Bad Gateway nginx/1.17.2?
- templates - 如何将自定义项目模板添加到 intellij 插件?
- c++ - 我在哪里得到“GDI_CapturingAnImage.h”?我想要 GDI_CapturingAnImage.h 文件
- flutter - 如何在颤动中增加滑块轨道宽度
- java - JPA 批量插入不会提高性能
- r - 是否有用于将表格按两行分组的 R 函数?
- python - 当我们拆分训练和测试时,我们希望将目标变量设为动态