CSV
The CSV Data Format uses Apache Commons CSV to handle CSV payloads (Comma Separated Values) such as those exported/imported by Excel.
Options
Option |
Type |
Description |
config |
CSVConfig |
Can be used to set a custom CSVConfig object. |
strategy |
CSVStrategy |
Camel uses by default CSVStrategy.DEFAULT_STRATEGY. |
autogenColumns |
boolean |
Camel 1.6.1/2.0: Is default true. By default, columns are autogenerated in the resulting CSV. Subsequent messages use the previously created columns with new fields being added at the end of the line. |
delimiter |
String |
Camel 2.4: Is default ,. Can be used to configure the delimiter, if it's not the comma. |
skipFirstLine |
boolean |
Camel 2.10: Is default false. While unmarshalling can be used to skip the first line of a CSV input which contains the CSV headers. |
Marshalling a Map to CSV
The component allows you to marshal a Java Map (or any other message type that can be converted in a Map) into a CSV payload.
An example: if you send a message with this map...
Map<String, Object> body = new HashMap<String, Object>();
body.put("foo", "abc");
body.put("bar", 123);
... through this route ...
from("direct:start").
marshal().csv().
to("mock:result");
... you will end up with a String containing this CSV message
Sending the Map below through this route will result in a CSV message that looks like foo,bar
Unmarshalling a CSV message into a Java List
Unmarshalling will transform a CSV messsage into a Java List with CSV file lines (containing another List with all the field values).
An example: we have a CSV file with names of persons, their IQ and their current activity.
Jack Dalton, 115, mad at Averell
Joe Dalton, 105, calming Joe
William Dalton, 105, keeping Joe from killing Averell
Averell Dalton, 80, playing with Rantanplan
Lucky Luke, 120, capturing the Daltons
We can now use the CSV component to unmarshal this file:
from("file:src/test/resources/?fileName=daltons.csv&noop=true").
unmarshal().csv().
to("mock:daltons");
The resulting message will contain a List<List<String>> like...
List<List<String>> data = "" class="code-object">String>>) exchange.getIn().getBody();
for (List<String> line : data) {
LOG.debug(String.format("%s has an IQ of %s and is currently %s",
line.get(0), line.get(1), line.get(2)));
}
Marshalling a List<Map> to CSV
Available as of Camel 2.1
If you have multiple rows of data you want to be marshalled into CSV format you can now store the message payload as a List<Map<String, Object>> object where the list contains a Map for each row.
File Poller of CSV, then unmarshaling
Given a bean which can handle the incoming data...
public void doHandleCsvData(List<List<String>> csvData)
{
}
... your route then looks as follows
<route>
<from uri="file:///some/path/to/pickup/csvfiles?delete=true&consumer.delay=10000" />
<unmarshal><csv /></unmarshal>
<to uri="bean:myCsvHandler?method=doHandleCsvData" />
</route>
Marshaling with a pipe as delimiter
Using the Spring/XML DSL:
<route>
<from uri="direct:start" />
<marshal>
<csv delimiter="|" />
</marshal>
<to uri="bean:myCsvHandler?method=doHandleCsv" />
</route>
Or the Java DSL:
CsvDataFormat csv = new CsvDataFormat();
CSVConfig config = new CSVConfig();
config.setDelimiter('|');
csv.setConfig(config);
from("direct:start")
.marshal(csv)
.convertBodyTo(String.class)
.to("bean:myCsvHandler?method=doHandleCsv");
CsvDataFormat csv = new CsvDataFormat();
csv.setDelimiter("|");
from("direct:start")
.marshal(csv)
.convertBodyTo(String.class)
.to("bean:myCsvHandler?method=doHandleCsv");
Using autogenColumns, configRef and strategyRef attributes inside XML DSL
Available as of Camel 2.9.2 / 2.10
You can customize the CSV Data Format to make use of your own CVSConfig and/or CVSStrategy. Also note that the default value of the autogenColumns option is true. The following example should illustrate this customization.
<route>
<from uri="direct:start" />
<marshal>
<csv autogenColumns="false" delimiter="|" configRef="csvConfig" strategyRef="excelStrategy" />
</marshal>
<convertBodyTo type="java.lang.String" />
<to uri="mock:result" />
</route>
<bean id="csvConfig" class="org.apache.commons.csv.writer.CSVConfig">
<property name="fields">
<list>
<bean class="org.apache.commons.csv.writer.CSVField">
<property name="name" value="orderId" />
</bean>
<bean class="org.apache.commons.csv.writer.CSVField">
<property name="name" value="amount" />
</bean>
</list>
</property>
</bean>
<bean id="excelStrategy" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField" value="org.apache.commons.csv.CSVStrategy.EXCEL_STRATEGY" />
</bean>
Using skipFirstLine option while unmarshaling
Available as of Camel 2.10
You can instruct the CSV Data Format to skip the first line which contains the CSV headers. Using the Spring/XML DSL:
<route>
<from uri="direct:start" />
<unmarshal>
<csv skipFirstLine="true" />
</unmarshal>
<to uri="bean:myCsvHandler?method=doHandleCsv" />
</route>
Or the Java DSL:
CsvDataFormat csv = new CsvDataFormat();
csv.setSkipFirstLine(true);
from("direct:start")
.unmarshal(csv)
.to("bean:myCsvHandler?method=doHandleCsv");
Unmarshaling with a pipe as delimiter
Using the Spring/XML DSL:
<route>
<from uri="direct:start" />
<unmarshal>
<csv delimiter="|" />
</unmarshal>
<to uri="bean:myCsvHandler?method=doHandleCsv" />
</route>
Or the Java DSL:
CsvDataFormat csv = new CsvDataFormat();
CSVStrategy strategy = CSVStrategy.DEFAULT_STRATEGY;
strategy.setDelimiter('|');
csv.setStrategy(strategy);
from("direct:start")
.unmarshal(csv)
.to("bean:myCsvHandler?method=doHandleCsv");
CsvDataFormat csv = new CsvDataFormat();
csv.setDelimiter("|");
from("direct:start")
.unmarshal(csv)
.to("bean:myCsvHandler?method=doHandleCsv");
Dependencies
To use CSV in your camel routes you need to add the a dependency on camel-csv which implements this data format.
If you use maven you could just add the following to your pom.xml, substituting the version number for the latest & greatest release (see the download page for the latest versions).
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-csv</artifactId>
<version>2.0.0</version>
</dependency>