2

目前我可以使用camel Bindy从POJO生成一个平面文件,但无法将页眉和页脚添加到完整文件中。

但是,当我尝试将页眉/页脚添加到文件时,它会添加到每条记录,但我需要将单个页眉/页脚添加到完整文件而不是文件中的每条记录。

下面是代码片段:

from("jpa:com.PACKAGENAME.RebatePayout?consumer.namedQuery=REBATE_PAYOUT&consumer.delay=500000&consumeLockEntity=true&consumeDelete=false")
    .routeId("rebateroute")
    .process(new Processor() {
        RebateOutputgenerator rop = new RebateOutputgenerator();
                @Override
                public void process(Exchange exchange) throws Exception {
                    exchange.getIn().setBody(rop.processEntities((RebatePayout) exchange.getIn().getBody()));
                    log.info("the exchange value is ", exchange);                         
                }
        })
        .process(new FahHeaderAndFooterHelper())
        .log("Fixed length format marshal....")
        .marshal(fixedLegth)
        .log("Fixed length format data....${body}")
        .to("file://C:/Users/vvakalap/Desktop/example/New folder?fileExist=Append&fileName=output.txt")
        .log("Data Saved in file...");

进程类是

public class FahHeaderAndFooterHelper implements Processor{
    @Override
    public void process(Exchange exchange) throws Exception {
        Map<String, Object> headerObjMap = new HashMap<String,Object>();
        headerObjMap.put(FahRecordHeader.class.getName(), new FahRecordHeader());
        if(exchange.getOut().getBody() == "null")
            exchange.getOut().setHeader(CAMEL_BINDY_FIXED_LENGTH_HEADER, headerObjMap);
        Map<String, Object> footerObjMap = new HashMap<String,Object>();
        footerObjMap.put(FahRecordFooter.class.getName(), new FahRecordFooter());
        exchange.getOut().setHeader(CAMEL_BINDY_FIXED_LENGTH_FOOTER, footerObjMap);
        exchange.getOut().setBody(exchange.getIn().getBody());
    }

POJO类

@Data
@Section(number=2)
@FixedLengthRecord(header = FahRecordHeader.class, footer = FahRecordFooter.class)
public class RebateFinalRecord implements Serializable {

    private static final long serialVersionUID = 7375828620208233805L;

    @DataField(pos = 1, length = 3)
    private String transactionRecordIdentifier;

    @DataField(pos = 4, length = 10)
    private String transactionNumber;

    @DataField(pos = 14, length = 5)
    private String transactionLineNumber;

    @DataField(pos = 19, length = 20)
    private String transactionDistributionType;

    @DataField(pos = 39, length = 30)
    private String eventTypeName;

    @DataField(pos = 69, length = 8)
    private String transactionDate;

    @DataField(pos = 77, length = 8)
    private String transactionEffectiveDate;

    @DataField(pos = 85, length = 5)
    private String transactingEntityValue;

    @DataField(pos = 90, length = 1)
    private String reciprocationFlag;

}

绑定类

@Data
public class FahRecordHeader {
    @DataField(pos = 1, length = 3)
    private String fileRecordIdentifier = "000";
    @DataField(pos = 4, length = 15)
    private String controlIdentifierOrSequenceNumber = "LSCD00000000006";
    @DataField(pos = 19, length = 20)
    private String source = "LSCD";
}

@Data
public class FahRecordFooter {

    @DataField(pos = 1, length = 70)
    private String footer = "footervalusforfahrecord for cashrebates";
    /*
     * @DataField(pos = 2, length = 9, align = "R", paddingChar = &#39;0&#39;)
     * private int numberOfRecordsInTheFile;
     */
}
4

3 回答 3

1

创建一个帮助方法,该方法返回MyClass的所有声明字段:

import java.lang.reflect.Field

class AnnotationUtil {

    public static Field[] getDeclaredFields(Class clazz, boolean recursively) {
        List<Field> fields = new LinkedList<Field>();
        Field[] declaredFields = clazz.getDeclaredFields();
        Collections.addAll(fields, declaredFields);

        Class superClass = clazz.getSuperclass();

        if(superClass != null && recursively) {
            Field[] declaredFieldsOfSuper = getDeclaredFields(superClass, recursively);
            if(declaredFieldsOfSuper.length > 0)
                Collections.addAll(fields, declaredFieldsOfSuper);
        }

        return fields.toArray(new Field[fields.size()]);
    }
}
@CsvRecord(separator = "|",  generateHeaderColumns = false)
class MyClass {

    @DataField(pos = 1, columnName = "Column1")
    String orderName;

    @DataField (pos = 2, columnName = "Column2")
    String transactionId
}

然后创建一个处理器:

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.dataformat.bindy.annotation.DataField;
import org.springframework.stereotype.Component;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Collectors;

@Component
class CSVHeaderProcessor implements Processor{
    @Override
    public void process(Exchange exchange) throws Exception {
       String fullFilePath = (String) exchange.getIn().getHeader("CSV_FILE_LOCATION");
        String header;
        File csvFile = new File(fullFilePath);

        if(!csvFile.exists()) {
            String headerRow = Arrays.stream((AnnotationUtil.getDeclaredFields(YourClass.class, false))).map(x -> x.getAnnotation(DataField.class).columnName()).collect( Collectors.joining( "," ));
            Files.write(Paths.get(csvFile.getPath()), headerRow.getBytes());
        }

    }
}

然后在您的路线中使用它:

 from("direct:handleCSV")
     .setHeader("CSV_FILE_LOCATION", simple("/tmp/yourfile.csv"))
     .process(csvHeaderProcessor)
     .marshal(bindy)
 .to("file:///tmp?fileName=yourfile.csv&fileExist=append")
于 2019-03-19T15:31:54.353 回答
0

您是否尝试设置to的hasHeaderhasFooter属性?@FixedLengthRecordtrue

@FixedLengthRecord(header = FahRecordHeader.class, 
                   footer = FahRecordFooter.class, 
                   hasHeader = true, 
                   hasFooter = true)

请参阅https://camel.apache.org/bindy.html#Bindy-4.FixedLengthRecord

于 2016-02-03T19:35:33.087 回答
0

这是很久以后的事了,但也许它仍然可以提供帮助。

您可以在添加 CAMEL_BINDY_FIXED_LENGTH_HEADER 和 CAMEL_BINDY_FIXED_LENGTH_FOOTER 标头时添加 FahHeaderAndFooterHelper 条件。

例如,如果文件不存在或页眉为空,以及当您的文件被视为页脚完整时的某些条件。

于 2018-05-17T08:14:23.380 回答