无法使用 Apache Camel Bindy 向文件添加页眉和页脚 [英] Unable to add header and footer to the file using Apache Camel Bindy

查看:27
本文介绍了无法使用 Apache Camel Bindy 向文件添加页眉和页脚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个带有页眉和页脚记录以及 json 负载作为正文的文件.页眉和页脚属性值将根据时间戳和记录总数动态变化(目前我计划使用来自属性的静态值来实现).我正在使用 FixedLengthDataFormat 来实现这一点.但是页眉和页脚记录没有被添加到文件中,文件只有 json 负载作为正文.有人可以帮助我实现这一目标吗?

I am trying to create a file with header and footer record along with json payload as body. Header and footer property values will be dynamic based on the timestamp and total number of records (At the moment I am planning to achieve with static values from properties). I am using FixedLengthDataFormat to achieve this. However header and footer records are not being added to the file, the file only has json payload as body. Can someone help me to achieve this?

我已经复制了下面的所有类文件.

I have copied all the class files below.

@Component
public class EmployeePackageRoute extends RouteBuilder {

    @Autowired
    private Header header;
    
    private Trailer footer;
    
    @SuppressWarnings("deprecation")
    @Override
    public final void configure() {
        System.out.println("fetching employee details from employee api");
        try {
            
            from("jetty://http://localhost:8084/employee-package/getEmployee")
            .unmarshal().json(JsonLibrary.Jackson, RecurringPaymentResults.class)
            .process(
                    ex -> {
                        System.out.println("+++++++++++++++++ "+ex.getIn().getBody());
                        RecurringPaymentResults result = ex.getIn().getBody(RecurringPaymentResults.class);
                        List<RecurringPaymentsDeduct> employee = result.getResults();
                        ex.getOut().setBody(employee);
                        System.out.println("**** Header ** "+header);
                    })
            .to("seda:employeeFeed");
            
            final DataFormat bindy = new BindyFixedLengthDataFormat(RecurringPaymentsDeduct.class);
            
            footer = new Trailer("TRAILER",3);
            
            Map<String, Object> headerObjMap = new HashMap<String,Object>();
            headerObjMap.put(Header.class.getName(), header);
            
            Map<String, Object> footerObjMap = new HashMap<String,Object>();
            footerObjMap.put(Trailer.class.getName(), footer);
            
            from("seda:employeeFeed")
            .log("process csv")
            .marshal(bindy)
            .log("csv processed")
            .process(
                    ex -> {
                        System.out.println("******************** "+ex.getIn().getBody());
                        
                        //ex.getOut().setHeader("header", header);
                        ex.getOut().setHeader(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_HEADER, headerObjMap);
                        ex.getOut().setBody(ex.getIn().getBody());
                        ex.getOut().setHeader(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_FOOTER, footerObjMap);
                        
                    }).to("file://C:\Users\testfolder?fileName=test.txt")
            .end();
            
                        
        } catch(Exception e) {
            System.out.println("Error occurred while processing employee data: "+e.getMessage());
            e.printStackTrace();
        }
    }
}

    @Data
    @Section(number = 2)
    @FixedLengthRecord(header = Header.class, footer = Trailer.class)
    public class RecurringPaymentsDeduct implements Serializable {
    
        private static final long serialVersionUID = 1L;
        
        @DataField(pos = 1, length = 10)
        public String RECTY;
        
        @DataField(pos = 2, length = 10)
        public String CLIID;
        
        @DataField(pos = 3, length = 10)
        public String INTCA;
        
        @DataField(pos = 4, length = 10)
        public String ORDNO;
        
        @DataField(pos = 5, length = 10)
        public String IOPER;
        
        @DataField(pos = 6, length = 10)
        public String INFTY;
        
        @DataField(pos = 7, length = 10)
        public String SUBTY;
        
        @DataField(pos = 8, length = 10)
        public String BEGDA;
        
        @DataField(pos = 9, length = 10)
        public String ENDDA;
        
        @DataField(pos = 10, length = 10)
        public String OBJPS;
        
    }


@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("test")
@Data
@Section(number = 1)
@FixedLengthRecord()
public class Header implements Serializable {

    private static final long serialVersionUID = 1L;

    @DataField(pos = 1, length = 5)
    private String header1;
    
    @DataField(pos = 2, length = 5)
    private String header2;
    
    @DataField(pos = 3, length = 15)
    private String header3;
    
    @DataField(pos = 4, length = 60)
    private String header4;
    
    @DataField(pos = 5, length = 15)
    private String header5;
    
    @DataField(pos = 6, length = 30)
    private String header6;
    
    @DataField(pos = 7, length = 30)
    private String header7;
    
    @DataField(pos = 8, length =  8, pattern = "YYYYMMDD")
    private String header8;
    
    @DataField(pos = 9, length = 6)
    private String header9;
    
    @DataField(pos = 10, length = 1)
    private String header10;
    
    @DataField(pos = 11, length = 2)
    private String header11;
    
    @DataField(pos = 12, length = 10)
    private String header12;
    
    @DataField(pos = 13, length = 10)
    private String header13;
    
    @DataField(pos = 14, length = 10)
    private String header14;
}


@Section(number = 3)
@FixedLengthRecord
public class Trailer implements Serializable {

    private static final long serialVersionUID = 1L;

    @DataField(pos = 1, length = 7)
    private String trailer;
    
    @DataField(pos = 2, length = 2)
    private int count;
    
    public String getTrailer() {
        return trailer;
    }
    public void setTrailer(String trailer) {
        this.trailer = trailer;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
}

推荐答案

我找到了答案.这个解决方案解决了我在不同阶段遇到的许多问题.

I found the answer. This solution had fixed many issues that I had in various stage.

问题 1) 使用 BindyFixedLengthDataFormat 向平面文件添加了动态页眉和页脚.顾名思义,它是固定长度的.我必须在生成主体后分配最大长度并修剪空格.(我仍然可能需要使用不同的类或方式来修剪空格).

Issue 1) Added dynamic header and footer to the flat file using BindyFixedLengthDataFormat. As the name suggests it's fixed length. I had to assign maximum length and trim the whitespaces after generating the body. (I still may need to use different class or way to trim the whitespaces).

问题 2) 我需要用 |" 替换管道分隔符.

Issue 2) I had the requirement to replace the pipe delimiter with |".

问题 3) 我没有使用 jetty 来公开硬编码的端点 url,而是使用了 rest 配置,这样主机名将不再是硬编码的,您可以部署到任何环境.

Issue 3) Instead of using jetty to expose the end point url which will be hard coded I have used rest configuration so that hostname will no longer be hard coded and you can deploy to any environment.

    @Component
    public class EmployeePackageRoute extends RouteBuilder {
    
        @Autowired
        private Header header;
        
        private Trailer footer;
        
        private String file_name;
        
        @SuppressWarnings("deprecation")
        @Override
        public final void configure() {
            
            System.out.println("fetching employee details from employee api");
            
            final SimpleDateFormat TARGET_DATE_FORMAT = new SimpleDateFormat("YYYYMMDDHHMMSS");
            String date = TARGET_DATE_FORMAT.format(new Date());
            
            String year = date.substring(0, 8);
            String hr = date.substring(9, 13);
    
            try {
                restConfiguration().component("jetty").port(8000).bindingMode(RestBindingMode.json);
                rest("/api/test/getTestResponse")
                .get().consumes(MediaType.APPLICATION_JSON_VALUE).route().setBody().constant("return test response");
                
                rest("/api/bcr/recurringPaymentsDeduct")
                .post().consumes(MediaType.APPLICATION_JSON_VALUE).type(RecurringPaymentResults.class).outType(ResponseEntity.class).route()
                .process(
                        ex -> {
                            
                            RecurringPaymentResults result = ex.getIn().getBody(RecurringPaymentResults.class);
                            List<RecurringPaymentsDeduct> employee = result.getResults();
                            file_name = Constants.FILE_NUMBER_DEV+"_"+date+"_"+Constants.AUMBCR_HRMD+result.getSequenceNumber()+"_"+Constants.DUT8G2I+".SAP";
                            header.setHeader7(Constants.FILE_NUMBER_DEV+"_"+date+"_"+Constants.AUMBCR_HRMD+result.getSequenceNumber()+"_"+Constants.DUT8G2I+".SAP");
                            
                            header.setHeader8(year);
                            header.setHeader9(hr);
                            header.setHeader10(Constants.ENVIRONMENT);
                            
                            footer = new Footer("Footer",(employee.size()+2));
                            
                            ex.getOut().setBody(employee);
                        })
                .to("seda:recurringPaymentsFeed");
                
                final DataFormat recurringPaymentsBindy = new BindyFixedLengthDataFormat(RecurringPaymentsDeduct.class);
                
                from("seda:recurringPaymentsFeed")
                .startupOrder(2)
                .log("add footer to the file")
                .process(
                        ex -> {
                            
                            Map<String, Object> headerObjMap = new HashMap<String,Object>();
                            headerObjMap.put(Header.class.getName(), header);
                            System.out.println(" *** file_name 1 - "+file_name);
                            Map<String, Object> footerObjMap = new HashMap<String,Object>();
                            footerObjMap.put(Footer.class.getName(), footer);
                            
                            ex.getOut().setHeader(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_HEADER, headerObjMap);
                            ex.getOut().setBody(ex.getIn().getBody());
                            ex.getOut().setHeader(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_FOOTER, footerObjMap);
                            
                        })
                .marshal(recurringPaymentsBindy)
                .convertBodyTo(byte[].class, "iso-8859-1")
                .setBody(body().regexReplaceAll("\\|", "\\|\""))
                .log("csv processed")
                .to("file://app/bcr-files?fileName=recurringPaymentsDeduct.SAP")
                .end();
                
                
            } catch(Exception e) {
                System.out.println("Error occurred while processing employee data: "+e.getMessage());
                e.printStackTrace();
            }
        }
        
    }

@Data
@Section(number = 2)
@FixedLengthRecord(header = Header.class, footer = Trailer.class)
public class RecurringPaymentsDeduct implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @DataField(pos = 1, length = 10, delimiter = "|", trim = true)
    public String RECTY;
    
    @DataField(pos = 2, length = 10, delimiter = "|", trim = true)
    public String CLIID;
    
    @DataField(pos = 3, length = 10, delimiter = "|", trim = true)
    public String INTCA;
    
    @DataField(pos = 4, length = 10, delimiter = "|", trim = true)
    public String ORDNO;
    
    @DataField(pos = 5, length = 10, delimiter = "|", trim = true)
    public String IOPER;
    
    @DataField(pos = 6, length = 10, delimiter = "|", trim = true)
    public String INFTY;
    
    @DataField(pos = 7, length = 10, delimiter = "|", trim = true)
    public String SUBTY;
    
    @DataField(pos = 8, length = 10, delimiter = "|", trim = true)
    public String BEGDA;
    
    @DataField(pos = 9, length = 10, delimiter = "|", trim = true)
    public String ENDDA;
    
    @DataField(pos = 10, length = 10, trim = true)
    public String OBJPS;
        
}

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("adp")
@Data
@Section(number = 1)
@FixedLengthRecord()
public class Header implements Serializable {

    private static final long serialVersionUID = 1L;

    @DataField(pos = 1, length = 5, delimiter = "|", trim = true)
    private String header1;
    
    @DataField(pos = 2, length = 5, delimiter = "|", trim = true)
    private String header2;
    
    @DataField(pos = 3, length = 15, delimiter = "|", trim = true)
    private String header3;
    
    @DataField(pos = 4, length = 60, delimiter = "|", trim = true)
    private String header4;
    
    @DataField(pos = 5, length = 15, delimiter = "|", trim = true)
    private String header5;
    
    @DataField(pos = 6, length = 30, delimiter = "|", trim = true)
    private String header6;
    
    @DataField(pos = 7, length = 30, delimiter = "|", trim = true)
    private String header7;
    
    @DataField(pos = 8, length =  8, pattern = "YYYYMMDD", delimiter = "|", trim = true)
    private String header8;
    
    @DataField(pos = 9, length = 6, delimiter = "|", trim = true)
    private String header9;
    
    @DataField(pos = 10, length = 1, delimiter = "|", trim = true)
    private String header10;
    
    @DataField(pos = 11, length = 2, delimiter = "|", trim = true)
    private String header11;
    
    @DataField(pos = 12, length = 10, delimiter = "|", trim = true)
    private String header12;
    
    @DataField(pos = 13, length = 10, delimiter = "|", trim = true)
    private String header13;
    
    @DataField(pos = 14, length = 10, align = "L", trim = true)
    private String header14;
}

@Data
@Section(number = 3)
@FixedLengthRecord()
public class Footer implements Serializable {

    private static final long serialVersionUID = 1L;

    @DataField(pos = 1, length = 7, delimiter = "|", trim = true)
    private String trailer;
    
    @DataField(pos = 2, length = 5, align = "L", trim = true)
    private int count;
    
    public Footer() {
        
    }
    
    public Footer(String trailer, int count) {
        this.trailer = trailer;
        this.count = count;
    }
}

这篇关于无法使用 Apache Camel Bindy 向文件添加页眉和页脚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆