Это на самом деле возможно при использовании Camel-Bindy с использованием модели FixedLengthRecord с табуляцией в качестве разделителя. Последнее поле в модели, кажется, нуждается в длине, но другие могут использовать табуляцию в качестве разделителя ....
Вот пример кода:
OrderHeader:
import java.util.Date;
import org.apache.camel.dataformat.bindy.annotation.DataField;
import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
@FixedLengthRecord()
public class OrderHeader {
@DataField(pos = 1, delimiter = "\t")
private int id;
@DataField(pos = 2, delimiter = "\t")
private String name;
@DataField(pos = 3, delimiter = "\t", pattern = "yyyy-MM-dd")
private Date date1;
@DataField(pos = 4, delimiter = "\t", pattern = "yyyy-MM-dd hh:mm:ss")
private Date date2;
@DataField(pos = 5, length = 1)
private int numerOfFile;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate1() {
return date1;
}
public void setDate1(Date date1) {
this.date1 = date1;
}
public Date getDate2() {
return date2;
}
public void setDate2(Date date2) {
this.date2 = date2;
}
public int getNumerOfFile() {
return numerOfFile;
}
public void setNumerOfFile(int numerOfFile) {
this.numerOfFile = numerOfFile;
}
}
Заказ:
import java.math.BigDecimal;
import org.apache.camel.dataformat.bindy.annotation.DataField;
import org.apache.camel.dataformat.bindy.annotation.FixedLengthRecord;
@FixedLengthRecord(header = OrderHeader.class)
public class Order {
@DataField(pos = 1, delimiter = "\t")
private int lp;
@DataField(pos = 2, delimiter = "\t")
private int id;
@DataField(pos = 3, delimiter = "\t")
private BigDecimal priceByOne;
@DataField(pos = 4, delimiter = "\t")
private BigDecimal count;
@DataField(pos = 5, length = 2)
private int foreignId;
public int getLp() {
return lp;
}
public void setLp(int lp) {
this.lp = lp;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public BigDecimal getPriceByOne() {
return priceByOne;
}
public void setPriceByOne(BigDecimal priceByOne) {
this.priceByOne = priceByOne;
}
public BigDecimal getCount() {
return count;
}
public void setCount(BigDecimal count) {
this.count = count;
}
public int getForeignId() {
return foreignId;
}
public void setForeignId(int foreignId) {
this.foreignId = foreignId;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("...lp:").append(lp).append("\n");
str.append("...id:").append(id).append("\n");
str.append("...priceByOne:").append(priceByOne).append("\n");
str.append("...count:").append(count).append("\n");
str.append("...foreignId:").append(foreignId).append("\n");
return str.toString();
}
XmlOrder:
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class XmlOrder extends OrderHeader {
public XmlOrder() {
}
private List<Order> line;
public XmlOrder(OrderHeader header, List<Order> lines) {
this.setDate1(header.getDate1());
this.setDate2(header.getDate2());
this.setId(header.getId());
this.setName(header.getName());
this.setNumerOfFile(header.getNumerOfFile());
this.setLines(lines);
}
public List<Order> getLines() {
return line;
}
public void setLines(List<Order> lines) {
this.line = lines;
}
}
Маршрут:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.converter.jaxb.JaxbDataFormat;
import org.apache.camel.dataformat.bindy.fixed.BindyFixedLengthDataFormat;
import com.stefan.test.fixedlengthtest.model.Order;
import com.stefan.test.fixedlengthtest.model.XmlOrder;
import com.stefan.test.fixedlengthtest.processors.ProcessOrder;
/**
* A Camel Java8 DSL Router
*/
public class MyRouteBuilder extends RouteBuilder {
public void configure() throws JAXBException {
// Initialize JAXB
JAXBContext jaxbContext = JAXBContext.newInstance(XmlOrder.class);
JaxbDataFormat jaxbDataFormat = new JaxbDataFormat(jaxbContext);
//@formatter:off
from("file:testdir").routeId("data-route")
.unmarshal(new BindyFixedLengthDataFormat(Order.class))
.to("log:test?showAll=true")
.log("Loop through data")
.process(new ProcessOrder())
.marshal(jaxbDataFormat)
.log("Order: \n${body}")
.log("DATA processed")
;
}
}
OrderProcessor:
import java.util.List;
import java.util.Map;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.dataformat.bindy.fixed.BindyFixedLengthDataFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.stefan.test.fixedlengthtest.model.OrderHeader;
import com.stefan.test.fixedlengthtest.model.XmlOrder;
public class ProcessOrder implements Processor {
private static final Logger logger = LoggerFactory.getLogger(ProcessOrder.class);
@Override
public void process(Exchange exchange) throws Exception {
Map<String, OrderHeader> headermap = exchange.getIn()
.getHeader(BindyFixedLengthDataFormat.CAMEL_BINDY_FIXED_LENGTH_HEADER, Map.class);
OrderHeader header = headermap.get(OrderHeader.class.getName());
logger.info("Processing order: {}", header.getId());
logger.info("...date1: {}", header.getDate1());
logger.info("...date2: {}", header.getDate2());
logger.info("...numberOfFile: {}", header.getNumerOfFile());
XmlOrder xmlorder = new XmlOrder(header, exchange.getIn().getBody(List.class));
exchange.getIn().setBody(xmlorder);
}
}
Этот пример маршрута выведет что-то вроде:
[ main] ProcessOrder INFO Processing order: 31
[ main] ProcessOrder INFO ...date1: 2018-11-01T00:00:00.000+0200
[ main] ProcessOrder INFO ...date2: 2018-10-31T00:05:16.000+0200
[ main] ProcessOrder INFO ...numberOfFile: 3
[ main] data-route INFO Order:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xmlOrder>
<date1>2018-11-01T00:00:00+02:00</date1>
<date2>2018-10-31T00:05:16+02:00</date2>
<id>31</id>
<name>name</name>
<numerOfFile>3</numerOfFile>
<lines>
<count>13</count>
<foreignId>14</foreignId>
<id>10</id>
<lp>1</lp>
<priceByOne>1</priceByOne>
</lines>
<lines>
<count>14</count>
<foreignId>14</foreignId>
<id>20</id>
<lp>2</lp>
<priceByOne>1</priceByOne>
</lines>
<lines>
<count>15</count>
<foreignId>14</foreignId>
<id>30</id>
<lp>3</lp>
<priceByOne>1</priceByOne>
</lines>
</xmlOrder>
[ main] data-route INFO DATA processed
Вы можете проверить полные источники для этого в github