Создание POJO из CSV, где поле представляет собой Enum

Я использую Bindy для создания Pojo из следующего файла CSV, где сторона — это Enum:

orderId,symbol,side,price,quantity
1, MSFT, SELL, 19, 8
2, MSFT, SELL, 20, 4
3, MSFT, BUY, 16, 16
public enum Side {
    BUY,
    SELL
}

Вот мой верблюжий маршрут:

 @Override
    public void configure() throws Exception {
        from("file:///Users/username/src/main/resources?fileName=orders.csv&noop=true&delay=1m")
                .unmarshal()
                .bindy(BindyType.Csv, Order.class).id("convertCsvToOrder")
                .to("kafka:" + "{{kafka.topic.neworder}}" + "{{kafka.broker.location}}").id("sendNewOrderToTopic")
                .routeId("new-order-csv");
    }

Я потратил много времени на чтение документации Apache Camel, но не могу найти примеры того, как предоставить конвертер, чтобы Side Enum в Pojo был построен правильно. На данный момент я получаю следующее исключение, когда Bindy пытается разобрать CSV. Цените, если кто-нибудь может дать руководство. Спасибо.

java.lang.IllegalArgumentException: Parsing error detected for field defined at the position: 3, line: 1
    at org.apache.camel.dataformat.bindy.BindyCsvFactory.setDataFieldValue(BindyCsvFactory.java:257) ~[camel-bindy-2.23.1.jar:2.23.1]
    at org.apache.camel.dataformat.bindy.BindyCsvFactory.bind(BindyCsvFactory.java:185) ~[camel-bindy-2.23.1.jar:2.23.1]
    at org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat.lambda$consumeFile$0(BindyCsvDataFormat.java:243) ~[camel-bindy-2.23.1.jar:2.23.1]
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[na:1.8.0_144]
    at java.util.stream.SliceOps$1$1.accept(SliceOps.java:204) ~[na:1.8.0_144]
    at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[na:1.8.0_144]
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[na:1.8.0_144]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_144]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_144]
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[na:1.8.0_144]
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[na:1.8.0_144]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_144]
    at java.util.stream.ReferencePipeline.forEachOrdered(ReferencePipeline.java:423) ~[na:1.8.0_144]
    at org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat.unmarshal(BindyCsvDataFormat.java:176) ~[camel-bindy-2.23.1.jar:2.23.1]
    at org.apache.camel.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:69) ~[camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548) ~[camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:138) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:101) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:454) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:223) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:187) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) [camel-core-2.23.1.jar:2.23.1]
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) [camel-core-2.23.1.jar:2.23.1]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_144]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_144]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_144]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: java.lang.IllegalArgumentException: No enum constant com.xxx.yyy.model.Side. SELL
    at java.lang.Enum.valueOf(Enum.java:238) ~[na:1.8.0_144]
    at org.apache.camel.dataformat.bindy.format.factories.EnumFormatFactory$EnumFormat.parse(EnumFormatFactory.java:49) ~[camel-bindy-2.23.1.jar:2.23.1]
    at org.apache.camel.dataformat.bindy.format.factories.EnumFormatFactory$EnumFormat.parse(EnumFormatFactory.java:36) ~[camel-bindy-2.23.1.jar:2.23.1]
    at org.apache.camel.dataformat.bindy.BindyCsvFactory.setDataFieldValue(BindyCsvFactory.java:252) ~[camel-bindy-2.23.1.jar:2.23.1]
    ... 31 common frames omitted

person gsdev    schedule 07.09.2019    source источник


Ответы (1)


Мне удалось понять, что здесь делать...

Существует аннотация под названием @BindyConverter, которую вы можете применить к полям. Я применил эту аннотацию к полю «Сторона», а затем создал класс с именем SideConverter, который выполняет преобразования.

@CsvRecord(separator = ",", crlf = "\r\n",  quoting = true, skipFirstLine = true)
public class Order implements Serializable {
    @DataField(pos = 1, required = true)
    private final Long orderId;

    @DataField(pos = 2, required = true)
    private final String symbol;

    @DataField(pos = 3, required = true)
    @BindyConverter(SideConverter.class)
    private final Side side;

    @DataField(pos = 4, required = true)
    private final Integer price;

    @DataField(pos = 5, required = true)
    private final Integer quantity;

    public Order(long orderId, String symbol, Side side, int price, int quantity) {
        this.orderId = orderId;
        this.symbol = symbol;
        this.side = side;
        this.price = price;
        this.quantity = quantity;
    }
public class SideConverter implements Format<Enum> {

    @Override
    public String format(Enum object) throws Exception {
        return object.name();
    }

    @Override
    public Enum parse(String string) throws Exception {
        Enum parsedValue = null;
        if (string.equals("BUY")) {
            parsedValue = Side.BUY;
        }

        if (string.equals("SELL")) {
            parsedValue = Side.SELL;
        }
        return parsedValue;
    }
}
person gsdev    schedule 07.09.2019