第168章 StAX
StAX Component リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Camel 2.9 以降で利用可能
StAX コンポーネントを使用すると、SAX ContentHandler を介してメッセージを処理できます。このコンポーネントのもう 1 つの機能は、Splitter EIP を使用する JAXB レコードの反復を可能にすることです。
Maven ユーザーは、このコンポーネントの
pom.xml に以下の依存関係を追加する必要があります。
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stax</artifactId>
<version>x.x.x</version>
<!-- use the same version as your Camel core version -->
</dependency>
URI 形式 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
stax:content-handler-class
例:
stax:org.superbiz.FooContentHandler
Camel 2.11.1 以降では、以下のように # 構文を使用して、レジストリーから
org.xml.sax.ContentHandler Bean を検索できます。
stax:#myHandler
コンテンツハンドラーを StAX パーサーとして使用する リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
処理後のメッセージボディーはハンドラー自体です。
以下に例を示します。
from("file:target/in")
.to("stax:org.superbiz.handler.CountingHandler")
// CountingHandler implements org.xml.sax.ContentHandler or extends org.xml.sax.helpers.DefaultHandler
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
CountingHandler handler = exchange.getIn().getBody(CountingHandler.class);
// do some great work with the handler
}
});
JAXB および StAX を使用してコレクションを繰り返し処理します。 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
最初に JAXB オブジェクトがあるとします。
たとえば、ラッパーオブジェクトのレコード一覧は以下のようになります。
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "records")
public class Records {
@XmlElement(required = true)
protected List<Record> record;
public List<Record> getRecord() {
if (record == null) {
record = new ArrayList<Record>();
}
return record;
}
}
および
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "record", propOrder = { "key", "value" })
public class Record {
@XmlAttribute(required = true)
protected String key;
@XmlAttribute(required = true)
protected String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
次に、処理する XML ファイルを取得します。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<records>
<record value="v0" key="0"/>
<record value="v1" key="1"/>
<record value="v2" key="2"/>
<record value="v3" key="3"/>
<record value="v4" key="4"/>
<record value="v5" key="5"/>
</record>
StAX コンポーネントは、Camel Splitter で XML 要素を反復処理する際に使用できる
StAXBuilder を提供します。
from("file:target/in")
.split(stax(Record.class)).streaming()
.to("mock:records");
stax は、Java コードで静的インポートできる org.apache.camel.component.stax.StAXBuilder の静的メソッドです。stax ビルダーは、デフォルトで、それが使用する XMLReader を認識します。Camel 2.11.1 以降では、以下のようにブール値パラメーターを false に設定するとこの機能をオフにできます。
from("file:target/in")
.split(stax(Record.class, false)).streaming()
.to("mock:records");
XML DSL を使用した前述の例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
上記の例は、XML DSL で以下のように実装できます。
<!-- use STaXBuilder to create the expression we want to use in the route below for splitting the XML file -->
<!-- notice we use the factory-method to define the stax method, and to pass in the parameter as a constructor-arg -->
<bean id="staxRecord" class="org.apache.camel.component.stax.StAXBuilder" factory-method="stax">
<!-- FQN class name of the POJO with the JAXB annotations -->
<constructor-arg index="0" value="org.apache.camel.component.stax.model.Record"/>
</bean>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<!-- pickup XML files -->
<from uri="file:target/in"/>
<split streaming="true">
<!-- split the file using StAX (ref to bean above) -->
<!-- and use streaming mode in the splitter -->
<ref>staxRecord</ref>
<!-- and send each splitted to a mock endpoint, which will be a Record POJO instance -->
<to uri="mock:records"/>
</split>
</route>
</camelContext>