[Camel in Action] 3-3. Camel 데이터 포맷 완전 정복 – CSV, JSON, Bindy

Camel 데이터 포맷(Data Format)이란?

데이터 포맷은 Java 객체와 바이트 스트림(또는 문자열) 사이를 변환하는 플러그인입니다. marshal()로 객체를 직렬화하고 unmarshal()로 역직렬화합니다. Camel은 20개 이상의 내장 데이터 포맷을 제공합니다.

JSON 데이터 포맷 – Jackson

<!-- pom.xml -->
<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-jackson-starter</artifactId>
</dependency>
// JSON 변환
from("direct:input")
    .unmarshal().json(JsonLibrary.Jackson, Order.class)  // JSON → Order
    .log("주문 ID: ${body.id}")
    .process(e -> e.getIn().getBody(Order.class).setStatus("PROCESSED"))
    .marshal().json(JsonLibrary.Jackson)  // Order → JSON
    .to("direct:output");

// List로 언마샬링
from("direct:jsonArray")
    .unmarshal().json(JsonLibrary.Jackson, List.class)
    .split(body())
        .log("항목: ${body}")
    .end();

CSV 데이터 포맷

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-csv-starter</artifactId>
</dependency>
CsvDataFormat csv = new CsvDataFormat();
csv.setDelimiter(';');
csv.setSkipHeaderRecord(true);  // 헤더 행 건너뛰기

from("file:csv-inbox?noop=true&include=.*\.csv")
    .unmarshal(csv)  // CSV → List<List<String>>
    .split(body())   // 각 행 처리
        .log("행 데이터: ${body}")
        .process(e -> {
            List<String> row = e.getIn().getBody(List.class);
            String orderId = row.get(0);
            double amount = Double.parseDouble(row.get(1));
            // 처리...
        })
    .end();

Bindy – 어노테이션 기반 포맷 매핑

Bindy는 Java 어노테이션으로 고정 길이 포맷, CSV, FIX(금융 메시지) 등을 매핑합니다.

// CSV 매핑 클래스
@CsvRecord(separator = ",", skipFirstLine = true)
public class OrderRecord {
    @DataField(pos = 1)
    private String orderId;

    @DataField(pos = 2)
    private String customerName;

    @DataField(pos = 3, pattern = "yyyy-MM-dd")
    private Date orderDate;

    @DataField(pos = 4, precision = 2)
    private BigDecimal amount;
}

// 고정 길이 포맷 매핑
@FixedLengthRecord
public class FixedOrderRecord {
    @DataField(pos = 1, length = 10)
    private String orderId;

    @DataField(pos = 11, length = 30)
    private String customerName;

    @DataField(pos = 41, length = 12, pattern = "yyyyMMddHHmm")
    private Date orderDate;
}
// Bindy 사용
BindyCsvDataFormat bindyCsv = new BindyCsvDataFormat(OrderRecord.class);

from("file:csv-inbox?noop=true")
    .unmarshal(bindyCsv)    // CSV → List<OrderRecord>
    .split(body())
        .log("주문: ${body.orderId} 금액: ${body.amount}")
    .end();

Avro – 스키마 기반 직렬화

// Kafka와 함께 Avro 사용
AvroDataFormat avro = new AvroDataFormat(Order.SCHEMA$);

from("kafka:orders?brokers=kafka:9092")
    .unmarshal(avro)
    .log("Avro 주문: ${body}");

데이터 포맷 자동 설정

# application.properties로 데이터 포맷 전역 설정
camel.dataformat.json-jackson.pretty-print=true
camel.dataformat.json-jackson.include=NON_NULL
camel.dataformat.csv.delimiter=;

Leave a Comment