java - OpenCSV java.lang.NoSuchMethodException : Unknown property 'X' on class Y

标签 java introspection opencsv

我正在尝试使用 openCSV 4.6 从 bean 列表中编写 CSV。但是,每当我运行程序时,我都会收到 CsvBeanIntrospectionException,然后收到 NoSuchMethodException: Unknown property 'Etrangers' on class 'class Properties' 尝试操作 Properties 类中 bean 的属性 Etrangers 时抛出内省(introspection)错误。

这是我的对象“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" };
}

对于行家

<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

REGIONS.json

最佳答案

我通过使用解决了

import com.opencsv.bean.HeaderColumnNameTranslateMappingStrategy; 

而不是

 import com.opencsv.bean.HeaderColumnNameMappingStrategy;

并使用

import org.apache.commons.collections4.comparators.FixedOrderComparato4r;

`
并通过创建 Hashmap 将 csv header 数据映射到 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" };

}

关于java - OpenCSV java.lang.NoSuchMethodException : Unknown property 'X' on class Y,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60467105/

相关文章:

java - LibGDX 简单的二维 block 图渲染

java - 将执行哪个重载方法以及为什么?

java - 使用 open csv 时从 csv 中删除双引号

csv - OpenCsv 读取带有转义分隔符的文件

java - 由 JDK 7u3 编译的 "Hello World!"程序是否可以与较旧的 JRE(例如 JRE 6)一起运行?

java - 如何通过 setter 设置最终字段?

python - 如何解释python3的帮助输出?

python - 检查python类属性

java - Eclipse 和 println 似乎在动态设置私有(private)最终静态字段的值上存在分歧

java - OpenCSV - 注册自定义转换器