49.15. 使用 Java DSL
下一步包含实例化与此记录类型关联的 DataFormat bindy 类,并提供 Java 软件包名称作为参数。
例如,以下命令使用类 BindyCsvDataFormat
(与与 CSV 记录类型关联的类对应),该类使用 com.acme.model
软件包名称初始化在此软件包中配置的模型对象。
// Camel 2.15 or older (configure by package name) DataFormat bindy = new BindyCsvDataFormat("com.acme.model"); // Camel 2.16 onwards (configure by class name) DataFormat bindy = new BindyCsvDataFormat(com.acme.model.MyModel.class);
49.15.1. 设置区域设置
bindy 支持在 dataformat 上配置区域设置,例如
// Camel 2.15 or older (configure by package name) BindyCsvDataFormat bindy = new BindyCsvDataFormat("com.acme.model"); // Camel 2.16 onwards (configure by class name) BindyCsvDataFormat bindy = new BindyCsvDataFormat(com.acme.model.MyModel.class); bindy.setLocale("us");
或者要使用平台默认区域设置,然后使用 "default" 作为区域设置名称。请注意,这需要 Camel 2.14/2.13.3/2.12.5。
// Camel 2.15 or older (configure by package name) BindyCsvDataFormat bindy = new BindyCsvDataFormat("com.acme.model"); // Camel 2.16 onwards (configure by class name) BindyCsvDataFormat bindy = new BindyCsvDataFormat(com.acme.model.MyModel.class); bindy.setLocale("default");
对于旧版本,您可以使用 Java 代码设置它,如下所示
// Camel 2.15 or older (configure by package name) BindyCsvDataFormat bindy = new BindyCsvDataFormat("com.acme.model"); // Camel 2.16 onwards (configure by class name) BindyCsvDataFormat bindy = new BindyCsvDataFormat(com.acme.model.MyModel.class); bindy.setLocale(Locale.getDefault().getISO3Country());
49.15.2. Unmarshaling
from("file://inbox") .unmarshal(bindy) .to("direct:handleOrders");
另外,您可以使用对数据格式的命名引用,然后在 Registry 中定义该格式,例如您的 Spring XML 文件:
from("file://inbox") .unmarshal("myBindyDataFormat") .to("direct:handleOrders");
Camel 路由将选择 inbox 目录中的文件,unmarshall CSV 记录到模型对象集合中,并将集合
发送到 'handleOrders' 所引用的路由。
返回的集合是一个 Map 对象列表。列表中的每个 map 包含 CSV 每行的模型对象。其后面的原因是 每行可以对应于多个对象。当您只是预期每行返回一个对象时,这可能会造成混淆。
每个对象都可以使用其类名称来检索。
List<Map<String, Object>> unmarshaledModels = (List<Map<String, Object>>) exchange.getIn().getBody(); int modelCount = 0; for (Map<String, Object> model : unmarshaledModels) { for (String className : model.keySet()) { Object obj = model.get(className); LOG.info("Count : " + modelCount + ", " + obj.toString()); } modelCount++; } LOG.info("Total CSV records received by the csv bean : " + modelCount);
假设您要从此映射中提取单个 Order 对象来处理路由中,您可以按照以下所示使用 Splitter 和 Processor 的组合:
from("file://inbox") .unmarshal(bindy) .split(body()) .process(new Processor() { public void process(Exchange exchange) throws Exception { Message in = exchange.getIn(); Map<String, Object> modelMap = (Map<String, Object>) in.getBody(); in.setBody(modelMap.get(Order.class.getCanonicalName())); } }) .to("direct:handleSingleOrder") .end();
请注意,Bindy 使用 CHARSET_NAME 属性或 CHARSET_NAME 标头,如 Exchange 接口中定义的字符集转换,以执行为 unmarshalling 收到的输入流的字符集转换。在一些生成者(如 file-endpoint)中,您可以定义一个 characterset。字符集转换可能已经由此制作者完成。有时,在将此属性或标头发送到 unmarshal 之前,您需要从交换中删除此属性或标头。如果您没有删除转换,则可能会进行两次,这可能会导致不需要的结果。
from("file://inbox?charset=Cp922") .removeProperty(Exchange.CHARSET_NAME) .unmarshal("myBindyDataFormat") .to("direct:handleOrders");
49.15.3. marshaling
要从模型对象集合生成 CSV 记录,您需要创建以下路由:
from("direct:handleOrders") .marshal(bindy) .to("file://outbox")