首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >,SuperCSV Dozer:如何避免嵌套对象的循环

,SuperCSV Dozer:如何避免嵌套对象的循环
EN

Stack Overflow用户
提问于 2014-06-24 20:39:50
回答 1查看 1.3K关注 0票数 0

我有以下课程..。

SurveyResponse.java

代码语言:javascript
复制
import java.util.List;

public class SurveyResponse {

private int age;

private Boolean consentGiven;

private List<Answer> answers;

public SurveyResponse() {
}

public SurveyResponse(final int age, final Boolean consentGiven, final List<Answer>   
answers) {
    this.age = age;
    this.consentGiven = consentGiven;
    this.answers = answers;
}

public int getAge() {
    return age;
}

public List<Answer> getAnswers() {
    return answers;
}

public Boolean getConsentGiven() {
    return consentGiven;
}

public void setAge(final int age) {
    this.age = age;
}

public void setAnswers(final List<Answer> answers) {
    this.answers = answers;
}

public void setConsentGiven(final Boolean consentGiven) {
    this.consentGiven = consentGiven;
}

@Override
public String toString() {
    return String.format("SurveyResponse [age=%s, consentGiven=%s, answers=%s]", age,
        consentGiven, answers);
}

}

Answer.java

代码语言:javascript
复制
public class Answer {
private Integer questionNo;

private String answer;

public Answer() {
}

public Answer(final Integer questionNo, final String answer) {
    this.questionNo = questionNo;
    this.answer = answer;
}

public String getAnswer() {
    return answer;
}

public Integer getQuestionNo() {
    return questionNo;
}

public void setAnswer(final String answer) {
    this.answer = answer;
}

public void setQuestionNo(final Integer questionNo) {
    this.questionNo = questionNo;
}

@Override
public String toString() {
    return String.format("Answer [questionNo=%s, answer=%s]", questionNo, answer);
}

}

还有我的类,它的循环工作很好,如下所示-

代码语言:javascript
复制
import java.io.FileWriter;
import java.util.Arrays;
import java.util.List;

import org.supercsv.cellprocessor.FmtBool;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.Token;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.dozer.CsvDozerBeanWriter;
import org.supercsv.io.dozer.ICsvDozerBeanWriter;
import org.supercsv.prefs.CsvPreference;


public class Main {

 private static final String[] FIELD_MAPPING = new String[] { "age", // simple field  
 mapping
                                                                    // (like  
 CsvBeanReader)
    "consentGiven", // as above
    "answers[0].questionNo", // indexed (first element) + deep mapping
    "answers[0].answer", "answers[1].questionNo", // indexed (second element) + deep   
mapping
    "answers[1].answer", "answers[2].questionNo", "answers[2].answer" };

/**
 * @param args
 * @throws Exception
 */
public static void main(final String[] args) throws Exception {
    writeWithDozerCsvBeanWriter();

}

private static void writeWithDozerCsvBeanWriter() throws Exception {

    final CellProcessor[] processors = new CellProcessor[] { new Token(0, null), // age
        new FmtBool("Y", "N"), // consent
        new NotNull(), // questionNo 1
        new Optional(), // answer 1
        new NotNull(), // questionNo 2
        new Optional(), // answer 2
        new NotNull(), // questionNo 3
        new Optional() }; // answer 4

    // create the survey responses to write
    final SurveyResponse response1 =
        new SurveyResponse(18, true, Arrays.asList(new Answer(1, "Twelve"), new 
Answer(2,
                "Albert Einstein"), new Answer(3, "Big Bang Theory")));
    final SurveyResponse response2 =
        new SurveyResponse(0, true, Arrays.asList(new Answer(1, "Thirteen"), new 
Answer(2,
                "Nikola Tesla"), new Answer(3, "Stargate")));
    final SurveyResponse response3 =
        new SurveyResponse(42, false, Arrays.asList(new Answer(1, null), new Answer(2,
                "Carl Sagan"), new Answer(3, "Star Wars")));
    final List<SurveyResponse> surveyResponses =
        Arrays.asList(response1, response2, response3);

    ICsvDozerBeanWriter beanWriter = null;
    try {
        beanWriter =
            new CsvDozerBeanWriter(new   
 FileWriter("C:\\Users\\Desktop\\Test.csv"),
                    CsvPreference.STANDARD_PREFERENCE);

        // configure the mapping from the fields to the CSV columns
        beanWriter.configureBeanMapping(SurveyResponse.class, FIELD_MAPPING);

        // write the header
        beanWriter.writeHeader("age", "consentGiven", "questionNo1", "answer1",
            "questionNo2", "answer2", "questionNo3", "answer3");

        // write the beans
        for (final SurveyResponse surveyResponse : surveyResponses) {
            beanWriter.write(surveyResponse, processors);
        }

    } finally {
        if (beanWriter != null) {
            beanWriter.close();
        }
    }
}

}

我想避免在字段映射处理器数组的循环,我们的应用程序有大约100到1000个答案。所以我写了下面这些不起作用的东西。有人能解释一下为什么下面的东西不起作用吗?

Main2.java

代码语言:javascript
复制
import java.io.FileWriter;
import java.util.Arrays;
import java.util.List;

import org.supercsv.cellprocessor.FmtBool;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.Token;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.dozer.CsvDozerBeanWriter;
import org.supercsv.io.dozer.ICsvDozerBeanWriter;
import org.supercsv.prefs.CsvPreference;

public class Main2 {

private static final String[] FIELD_MAPPING = new String[] { "age", "consentGiven",
    "answers.questionNo", "answers.answer" };

/**
 * @param args
 * @throws Exception
 */
public static void main(final String[] args) throws Exception {
    writeWithDozerCsvBeanWriter();

}

private static void writeWithDozerCsvBeanWriter() throws Exception {

    final CellProcessor[] processors = new CellProcessor[] { new Token(0, null), // age
        new FmtBool("Y", "N"), // consent
        new NotNull(), // questionNo
        new Optional() // answer
        };

    // create the survey responses to write
    final SurveyResponse response1 =
        new SurveyResponse(18, true, Arrays.asList(new Answer(1, "Twelve"), new 
       Answer(2,
                "Albert Einstein"), new Answer(3, "Big Bang Theory")));
    final SurveyResponse response2 =
        new SurveyResponse(0, true, Arrays.asList(new Answer(1, "Thirteen"), new 
       Answer(2,
                "Nikola Tesla"), new Answer(3, "Stargate")));
    final SurveyResponse response3 =
        new SurveyResponse(42, false, Arrays.asList(new Answer(1, null), new Answer(2,
                "Carl Sagan"), new Answer(3, "Star Wars")));
    final List<SurveyResponse> surveyResponses =
        Arrays.asList(response1, response2, response3);

    ICsvDozerBeanWriter beanWriter = null;
    try {
        beanWriter =
            new CsvDozerBeanWriter(new  
 FileWriter("C:\\Users\\Desktop\\Test.csv"),
                    CsvPreference.STANDARD_PREFERENCE);

        // configure the mapping from the fields to the CSV columns
        beanWriter.configureBeanMapping(SurveyResponse.class, FIELD_MAPPING);

        // write the header
        beanWriter.writeHeader("age", "consentGiven", "questionNo1", "answer1");

        // write the beans
        for (final SurveyResponse surveyResponse : surveyResponses) {
            beanWriter.write(surveyResponse, processors);
        }

    } finally {
        if (beanWriter != null) {
            beanWriter.close();
        }
    }
}

}

这里是错误

代码语言:javascript
复制
6 [main] INFO org.dozer.config.GlobalSettings - Trying to find Dozer configuration   
file: dozer.properties

14 [main] WARN org.dozer.config.GlobalSettings - Dozer configuration file not found: 
dozer.properties.  Using defaults for all Dozer global properties.
 15 [main] INFO org.dozer.DozerInitializer - Initializing Dozer. Version: 5.4.0, Thread       
 Name: main

64 [main] INFO org.dozer.jmx.JMXPlatformImpl - Dozer JMX MBean 
[org.dozer.jmx:type=DozerStatisticsController] auto registered with the Platform MBean 
Server

65 [main] INFO org.dozer.jmx.JMXPlatformImpl - Dozer JMX MBean 
[org.dozer.jmx:type=DozerAdminController] auto registered with the Platform MBean 
Server

68 [main] INFO org.dozer.DozerBeanMapper - Initializing a new instance of dozer bean 
mapper.

 156 [main] ERROR org.dozer.MappingProcessor - Field mapping error -->

MapId: null
Type: null
Source parent class: SurveyResponse
Source field name: answers.questionNo
Source field type: null
 Source field value: null
Dest parent class: org.supercsv.io.dozer.CsvDozerBeanData
Dest field name: columns
Dest field type: java.util.List
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at  
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.dozer.util.ReflectionUtils.invoke(ReflectionUtils.java:323)
at 
  org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.
  getDeepSrcFieldValue(GetterSetterPropertyDescriptor.java:122)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.
 getPropertyValue(GetterSetterPropertyDescriptor.java:75)
at org.dozer.fieldmap.FieldMap.getSrcFieldValue(FieldMap.java:84)
at org.dozer.MappingProcessor.mapField(MappingProcessor.java:275)
at org.dozer.MappingProcessor.map(MappingProcessor.java:248)
at org.dozer.MappingProcessor.map(MappingProcessor.java:197)
at org.dozer.MappingProcessor.map(MappingProcessor.java:187)
at org.dozer.MappingProcessor.map(MappingProcessor.java:133)
at org.dozer.MappingProcessor.map(MappingProcessor.java:128)
at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:127)
at org.supercsv.io.dozer.CsvDozerBeanWriter.write(CsvDozerBeanWriter.java:132)
at MainAvoidIndexing.writeWithDozerCsvBeanWriter(MainAvoidIndexing.java:68)
at MainAvoidIndexing.main(MainAvoidIndexing.java:29)

     Exception in thread "main" java.lang.IllegalArgumentException: object is not an 
     instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at 
        sun.reflect.DelegatingMethodAccessorImpl.
   invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.dozer.util.ReflectionUtils.invoke(ReflectionUtils.java:323)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.
   getDeepSrcFieldValue(GetterSetterPropertyDescriptor.java:122)
at  
  org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.
  getPropertyValue(GetterSetterPr  
    opertyDescriptor.java:75)
at org.dozer.fieldmap.FieldMap.getSrcFieldValue(FieldMap.java:84)
at org.dozer.MappingProcessor.mapField(MappingProcessor.java:275)
at org.dozer.MappingProcessor.map(MappingProcessor.java:248)
at org.dozer.MappingProcessor.map(MappingProcessor.java:197)
at org.dozer.MappingProcessor.map(MappingProcessor.java:187)
at org.dozer.MappingProcessor.map(MappingProcessor.java:133)
at org.dozer.MappingProcessor.map(MappingProcessor.java:128)
at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:127)
at org.supercsv.io.dozer.CsvDozerBeanWriter.write(CsvDozerBeanWriter.java:132)
at MainAvoidIndexing.writeWithDozerCsvBeanWriter(MainAvoidIndexing.java:68)
at MainAvoidIndexing.main(MainAvoidIndexing.java:29)
EN

回答 1

Stack Overflow用户

发布于 2014-06-25 04:09:16

answers字段在SurveyResponse中是一个List,所以您必须使用索引映射来配置CsvDozerBeanWriter。索引映射实际上不是循环,而是Dozer如何知道要填充列表中的哪个元素。如果要忽略一个列,这是非常重要的-它实际上会为该列插入一个null元素。

如果您不使用索引映射(只使用"answers"),那么您需要配置一个单元处理器,该处理器可以接受List<Answer>并将其转换为可以用作CSV的东西。

动态配置字段映射

(结果并不是你要求的那样,但我会离开,以备将来参考)

这并不意味着您必须使用静态字符串数组配置字段映射。可以使用简单的for-循环动态填充数组。例如,

代码语言:javascript
复制
    String[] fieldMapping = new String[10];
    fieldMapping[0] = "age";
    fieldMapping[1] = "consentGiven";
    int answerStartIndex = 2;
    int answerEndIndex = 8;
    for (int i = answerStartIndex; i <= answerEndIndex; i++){
        fieldMapping[i] = String.format("answers[%s].questionNo", 
            i - answerStartIndex);
    }
    fieldMapping[9] = "age";

这将使您的fieldMapping值为:

代码语言:javascript
复制
[age, consentGiven, answers[0].questionNo, answers[1].questionNo,
 answers[2].questionNo, answers[3].questionNo, answers[4].questionNo,
 answers[5].questionNo, answers[6].questionNo, age]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24395851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档